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