08 June, 2019

GraphQL (Graph Query Language)

GraphQL is Facebook’s attempt at addressing the shortcomings of RESTful APIs.

Its' a strongly typed query language for our API (like Typescript for your API) that makes it easier to declaratively fetch and mutate data without having to worry about backend implementation details. Unlike a classic REST architecture, it lets clients fetch lots of related data in a single request.

The core difference between GraphQL and REST can be boiled down as follows:

REST has a set of endpoints that each return fixed data structures GraphQL has a single endpoint that returns flexible data structures. Request details are in the POST body (Can do GET request for queries).

This works because with GraphQL the client can dictate the shape of the response. It submits a query to the server that precisely describes its data needs. The server resolvesthat query and returns only the data the client asked for.

In REST the shape of the response is determined by server. In GraphQL it is:

  • Based on a schema There is a well defined data model available, so the client knows exactly how this data will be returned and how to perform the queries.
  • Flexibility The client decides which data should be available in the result. This avoids unused data in the server response.
  • Can be implemented in any language GraphQL is available for many different languages and can work beside REST with no problem, it’s basically another way to expose data. It also works with any database and it’s up to the developer to decide what is available in the schema and what is not.

Terminology

Mutation
A Mutation is equivalent to a PUT request.
Resolver
Resolvers are what the method should run given the arguments and what you want to return. They are like controllers but much more flexible and composable. They do one thing but are aware of what happened before them and can set up what happens after them.
If properties match up then GraphQL will automatically resolve the type; otherwise write a custom resolver to tell GraphQL how to resolve the type.
Context
Like dependency injection for your resolvers. aka. inject global things. Share state across resolvers. eg. If you wanted to use a3rd party service eg. stripe - put in the context.
Fragments
A template for a group of fields that can only be use in queries. Then if you need to change it you only need to in one place. + Separation of concerns.
Unions and Interfaces
Use them if you have a group of different return types. enums only return strings so interfaces and unions allow you to group types for a selection so you can group types to return. Interfaces optimises (removes repetition) for the query. You need to make a property for the interfaces so GraphQL can resolve if the interface is a cat or a dog .eg given an animal is it a cat or a dog. unions can return a collection of types
Animal {
    __resolverType(animal, ctx, info). // theres no args on interfaces
}