GraphQL

GraphQL #

History #

  • Created by Facebook in 2012
  • Opensourced in 2015

About #

  • Roles: Describes data and functions available between client-server applications
  • Plugs to a database or an API
  • Doesn’t store data
  • Communication with JSON
  • Main purpose: Used as a Gateway

What problems does it solve? #

  • The one endpoint per resources principle of REST requires to make several HTTP calls if we want to display a lot of different information in one page
  • It’s very costy for mobile apps, mostly when we use data instead of wifi
  • Versioning
    • Either we need to version a REST API if we need to change our outputs /v1, /v2, …
    • Or we never remove fields and we just add new ones, which will lead to a dirty model
  • No unique REST standard, which lead to the explosion of REST standards: Open API, OData, Hydra, JSend, …
  • REST is modeled after HTTP
    • Many modern apps require real-time updates (Publish/Subscribe)
    • HTTP communication is based on a request and a response
    • HTTP is not designed to push updates without any request

The solution #

  • Query aggregates of resources (e.g. tweets and profile, in one round trip), even from different domains
  • Query an explicit list of fields, never a complete resource
  • Provide a schema describing the syntax of the request and response
  • Be a standard, but not too tied to the HTTP protocol
  • Support Publish/Subscribe scenarios out of the box
  • Shift the emphasis from the server to the client.

Steps #

  • Install IDE: Graphiql
  • Install a GraphQL server (ex: https://github.com/overblog/GraphQLBundle, https://www.apollographql.com/)
  • Declare types
    • Types: Data types to be queried (Int, Float, String, Boolean, ID, Enum, Custom types, …)
      • type Article {
          name: String!
          status: Status!
        }
        
      • interface Publish {
          id: ID!
          name: String!
          createdAt: Date
        }
        type Article implements Publish {
          content: String!
        }
        
  • Define main types
    • QUERY
      • List of functions to get data
      • Can take parameters and returns Types
      • type Query {
          article(id: ID!): Article
          articles(): [Article]
        }
        
    • MUTATION
      • For updating data
      • Takes ‘input’ as parameters and returns Types
      • input ArticleInput {
          id: Int!
          title: String
        }
        saveArticle(input: ArticleInput!): Article
        
  • Define resolvers
    • A resolver is a function that tells where to get the data

Cons #

  • Cannot have HTTP cache because only one endpoint is used with a POST method
  • Rewrite the same Models we wrote for the ORM
  • Difficulty to implement authentication
  • Difficulty of monitoring

Pros #

  • Allows to have easily an unique gateway for different sources of data
  • The frontend can decide himself of the output he wants to get