GraphQL: From Zero To Scala

Jérémie Astori
24 March 2017 — NE Scala NYC

Switch to high contrast mode

QR code to the URL of these slides

https://astori.fr/graphql-nescala

About me

Jérémie's profile picture
@astorije on Twitter, GitHub, …

CloudHealth Technologies logo

New to Scala / GraphQL / giving talks

Ubeer

Ubeer

Client
Vanilla JS
Server
Sangria
Akka HTTP

Ubeer

Brewery
ID
Name
Address
Phone
Website
Description
Beer
ID
Brewery ID
Style ID
Name
ABV
Description
Style
ID
Name
Category ID
Category
ID
Name

Demo time

Windows BSOD

Ubeer demo

If I were a REST API

/breweries?city=Brooklyn


            [{
              "name": "Brooklyn Brewery",
              "address": "79 North Eleventh Street",
              "website": "http://www.brooklynbrewery.com/"
            }]
          

If I were a REST API

  • /breweries?city=Brooklyn → Over-fetching
  • /v2/breweries?city=Brooklyn → Maintenance
  • /beer/:id → Multiple round trips
  • /breweries?city=Brooklyn
    &fields=name,beers.name,beers.abv
    Custom DSL

Expected response


            {
              "breweries": [{
                "name": "Brooklyn Brewery",
                "address": "79 North Eleventh Street",
                "website": "http://www.brooklynbrewery.com/",
                "beers": [{
                  "name": "Black Chocolate Stout",
                  "abv": 10,
                  "description": "This is the famous Brooklyn […]",
                  "style": {
                    "name": "American-Style Stout"
                  }
                }]
              }]
            }
          

Expected response


            {
              "breweries": [{
                "name": "Brooklyn Brewery",
                "address": "79 North Eleventh Street",
                "website": "http://www.brooklynbrewery.com/",
                "beers": [{
                  "name": "Black Chocolate Stout",
                  "abv": 10,
                  "description": "This is the famous Brooklyn […]",
                  "style": {
                    "name": "American-Style Stout"
                  }
                }]
              }]
            }
          

GraphQL query


            {
              breweries {
                name
                address
                website
                beers {
                  name
                  abv
                  description
                  style {
                    name
                  }
                }
              }
            }
          

GraphQL query


            {
              breweries {
                name
                address
                website
              }
            }
          

Sangria logo
GraphQL

by Facebook

What is GraphQL

  • Query language and type system for APIs
  • ∀-agnostic
  • Versionless design

Let’s hack some queries

Hackerman with his Power Glove

GraphiQL demo

More examples at: https://github.com/astorije/ubeer#query-examples

Sangria logo

by Oleg Ilyenko
@easyangel

Sangria

  • Schema definition, query parsing and execution
  • Translates GraphQL types to Scala types

Query Type


            type Query {
              # Returns a beer
              beer(id: Int!): Beer
            }
          

Query Type


              type Query {
                # Returns a beer
                beer(id: Int!): Beer
              }
            

              {
                beer(id: 360) {
                  name         
                  abv          
                }              
              }
            

Example

Query Type


            val Id = Argument("id", IntType)

            val QueryType = ObjectType("Query", fields[Repository, Unit](
              Field("beer", OptionType(BeerType),    
                description = Some("Returns a beer"),
                arguments = Id :: Nil,               
                resolve = c => c.ctx.beer(c.arg(Id)) 
              )                                      
            ))
          

Source

Type derivation


              type Style {
                id: Int!
                name: String!
                beers: [Beer!]!
                category: Category!
              }
            

              case class Style(
                id: Int,
                category_id: Int,
                name: String
              )
            

Source

Type derivation


            val StyleType = deriveObjectType[Repository, Style](
              ObjectTypeDescription("A style of beer, […]"),
              AddFields(Field("beers", ListType(BeerType),   
                resolve = c => c.ctx.beersByStyle(c.value.id)
              )),                                            
              ReplaceField("category_id", Field("category", CategoryType,
                resolve = c => c.ctx.category(c.value.category_id).get   
              ))                                                         
            )
          

Source

Thanks!

Resources

QR code to the URL of these slides