GraphQL - A Query Language for APIs

M A Hossain Tonu

Software Development Lead,
Vantage Labs Dhaka
mahtonu@vantage.com

What is GraphQL?

  • A new API standard/spec.
  • Database agnostic

  • Language of your API

  • Strongly Typed

  • Declarative data fetching

  • via one endpoint

What is GraphQL?

declarative data fetching where a client specifies what data it needs to an API

What is GraphQL?

Instead of multiple endpoints that return fixed data structures, a GraphQL server only exposes a single endpoint and responds with precisely the data a client asked for

Powerful better alternative to REST 

  • Single endpoint

  • One API for different frontend frameworks

  • Efficient data loading, query defines the batch sizes

  • Fast development = Rapid Feature Development

  • Easy Design changes

Data Fetching with REST vs GraphQL

Tonu

Post 1

Asad,

Post 2

Zia

Requirements are,


- Display the User name
- Display his last 2 posts
- Display two of his friends name

Data Fetching with REST vs GraphQL

/users/<id>
/users/<id>/posts
/users/<id>/friends

HTTP Get

{
	"user": {
        "id": "qrt123ter5",
        "name": "Tonu",
        "age": 35,
        "address": "...",
        "facebook_url", "..."
    }
}

Tonu

Post 1

Asad,

Zia

Post 2

Hey! I need only name!

Data Fetching with REST vs GraphQL

/users/<id>
/users/<id>/posts
/users/<id>/friends

HTTP Get

{
	"posts": [{
        "id": "abc123trtr5",
        "title": "Learn Angular",
        "content": "...."
    }
    ...         
    ]
}

Tonu

Post 1

Asad,

Zia

Post 2

Hey! Another HTTP and I don't want that content!

Data Fetching with REST vs GraphQL

/users/<id>
/users/<id>/posts
/users/<id>/friends

HTTP Get

{
	"friends": [{
        "id": "tyu123trtr5",
        "name": "Asad",
        "age": 35,
      	"address": "...",
      	"facebook_url": ""
    }
    ...           
    ]
}

Tonu

Post 1

Asad

Zia

Post 2

Hey! Not all those fields and friends!

Data Fetching with REST vs GraphQL

HTTP POST

{
	"data": {
      { "User": {
         "name": "Tonu",
         "posts": [
            {"title":"Learn Angular"}
          ],
         "friends": [
            {"name":"Asad"}, 
            {"name":"Zia"}
          ]
      }
    }           
}

Tonu

Post 1

Asad,

Zia

Post 2

{
  query {
    User(id: "qrt123ter5") {
           name,
  	  posts {
  	    title
		}
	   friends(last: 2) {
            name
        }
    }
  }
}

You declare what you want.

GraphQL delivers what was expected.

No more Over- and Underfetching

Schema Definition Language (SDL)

type User {
  name: String!
  age: Int!
}

Schema Definition Language (SDL)

type Post {
  title: String!
  author: User!
}

Schema Definition Language (SDL)

type User {
  name: String!
  age: Int!
  posts: [Post!]!
}

Fetching Data with Queries

{
  allUsers {
    name
  }
}

Fetching Data with Queries

{
  allUsers {
    name
  }
}

root field

Payload

Fetching Data with Queries

{
  "allUsers": [
    { "name": "Tonu" },
    { "name": "Zia" },
    { "name": "Asad" }
  ]
}

Server responds

Fetching Data with Queries

{
  allUsers {
    name
    age
  }
}

More fields can be added

Fetching Data with Queries

{
  allUsers {
    name
    age
    posts {
      title
    }
  }
}

Even one-to-many relations

Fetching Data with Queries

{
  allUsers(last: 2) {
    name
  }
}

Supports arguments

Writing Data with Mutations

mutation {
  createUser(name: "Zia", age: 56) {
    name
    age
  }
}

Mutations for Create, Update and Delete

Writing Data with Mutations

"createUser": {
  "name": "Zia",
  "age": 56,
}

Writing Data with Mutations

mutation {
  createUser(name: "Zia", age: 56) {
    id
  }
}

Realtime Updates with Subscriptions

subscription {
  newUser {
    name
    age
  }
}

Realtime Updates with Subscriptions

{
  "newUser": {
    "name": "Asad",
    "age": 23
  }
}

The Schema root types

type Query { ... }
type Mutation { ... }
type Subscription { ... }

The Schema root types

type Query {
  allUsers(last: Int): [User!]!
}

The Schema root types

type Mutation {
  createUser(name: String!, age: Int!): User!
}

The Schema root types

type Subscription {
  newUser: User!
}

The Schema root types

type Query {
  allUsers(last: Int): [User!]!
}

type Mutation {
  createUser(name: String!, age: Int!): User!
}

type Subscription {
  newUser: User!
}

type User {
  name: String!
  age: Int!
  posts: [Post!]!
}

type Post {
  title: String!
  author: User!
}

GraphQL server with a connected database

GraphQL server with a connected database

 In the setup, you have a single (web) server that implements the GraphQL specification. When a query arrives at the GraphQL server, the server reads the query’s payload and fetches the required information from the database. This is called resolving the query.

GraphQL layer that integrates existing systems

Legacy Systems

Microservices

3rd Party API

Resolver Functions

When the server receives a query, it will call all the functions for the fields that are specified in the query’s payload. It thus resolves the query and is able to retrieve the correct data for each field. Once all resolvers returned, the server will package data up in the format that was described by the query and send it back to the client.

Resolver Functions

HTTP POST

{
  query {
    User(id: "qrt123ter5") {
           name,
	   friends(last: 2) {
            name
            age
        }
    }
  }
}
User(id: String!): User
name(user: User!): String
age(user: User!): Int
friends(last: Int, user User!): [User!]!

Fetching data from a REST APIs

  1. construct and send HTTP request (e.g. with fetch in Javascript)
  2. receive and parse server response
  3. store data locally (either simply in memory or persistent)
  4. display data in the UI

GraphQL Client Libraries

  1. describe data requirements
  2. display data in UI

GraphQL Client Libraries

All the lower-level networking tasks as well as storing the data should be abstracted away and the declaration of data dependencies should be the dominant part.

GraphQL Client Libraries

GraphQL Playground

Challenges

  • Server side caching compared to REST
  • REST like error codes

 

Learning Entrypoints

Made with Slides.com