GraphQL

GraphQL

Yes, I couldn't resist to post that one! Atomium from Belgium.

GraphQL seems to bring some inquietude among data architects who believe this is a leaky abstraction.

REST is easier to understand at first glance. REST stand for representational state transfer. Server should not hold any information specific to the client, client should not have awareness of what is behind the representation.

Usually a REST request looks like this:

POST /user HTTP/1.1
Authorization: Bearer ****
Content-Type application/json
Accept: application/json

{ "callname": "Jhon" }

And respond like this

HTTP/1.1 201 created
Content-Type: application/json
Location: /user/42

{"callname":"Jhon","id":42}

In that example, the client would be able to query the user:

GET /user/42 HTTP/1.1
Authorization: Bearer ****
Accept: application/json

Very easy to understand. Each resource has his own URL and respond to HTTP verbs.

Now comes the classic problem. What if I need to have many views on an object ? Let say, an order, with its lines.

Here are possible GET requests:

GET /order/31 -> Full order
GET /order/31/item -> Order items
GET /order/31/header -> Order metadata (client, shipping)
GET /client/72 -> A client
  • Should the client be returned in order header OR should we return a resource location ?
  • Should we allow field digging by using paths ?

Some will create views for the ui-layer. Some kind of meta resources linked to application screen. This permits to expose specific views.

I also saw JsonPath used as XPaht to query the document.

Designing a REST API can be tough and one can quickly end up binding it to the client side. It's leaky abstraction where server is aware of client needs before they are expressed.

Here come GRaphQL

In GraphQL, one design an abstraction layer through a schema. The schema describes what is available, not HOW.

type Query {
  order(id:Number): Order
}
type Order {
  client: Client!
  items: [Item]!
  total: Number!
}
type Item {
  price: Number!
  name: String!
}

Now, one can query exactly what he needs.

{
  order(id:31) {
    total
  }
}

As you can see, like REST, I do not have to be aware of what is behind that total field. Is it calculated ? Extracted from a database ? Maybe there is a web service behind ?

The only think I know is that I can access orders by their ID and for each, I can ask exactly what I need.

The server do not need to know how it will be used either. He just expose what clients are allowed to access!

The other problem is mutations. In GraphQL, those are defined as...mutations.

type Mutation {
  createOrder(order:OrderInput): Order
  updateOrder(id:Int,orderInput): Order
  addOrderLine(id:Int,Item): Order
}

That's how a mutation is declared. Then we define the OrderInput type:

input OrderInput {
  clientId: Int!,
  items:[Int]!
}

As one can see, it's well defined.

GraphQL also provides a mean to pass structured data in parameters through variables:

query: mutation createOrder($order:OrderInput) { 
  createOrder(order:$order) { id }
}
variables: { "$order" : { "clientId":42,"items": [ 7,3,9,2 ] } }

The above query create an order and retrieves only the id

And if you like being sloppy (can looks good in simple cases though):

mutation {
 createOrder({ clientId:42,items:[7,3,9,2] })
}

Take away ?

GraphQL permits a good separation of client and server. It can also lower payload and time consumed making specific endpoints.

GraphQL permits flexibility both on the server side (implementation can change freely) and client side (client can be very flexible on input).

GraphQL standardise how to define schemas. It exposes the schema too. This makes it easy to create tooling.

Misconceptions

  • GraphQL is a layer on top of a database which permits to query it like a graph.

GraphQL is more of an integration platform. GraphQL abstract and combine varied datasources. GraphQL permit a natural aggregation.

  • GraphQL permits to transform output like XQuery/XSLT would do

No, but it permits to retrieve a subset of a predefined output. (e.g. an order without its lines)

Some extensions permits to lift up fields by using directives. Directives are something to dig in if evaluating GraphQL. Look at builtin "@include" or "@skip" (must be supported by compliant servers)


To view or add a comment, sign in

More articles by Christian Baune

  • Look at this, can you do better in Java/Kotlin/PHP ?

    Quick easy post to highlight the XQuery advantage. Replicate this in your favorite language.

  • Optimization 2

    Computing size VS Fast and slow pointers The graph above show the performance of two algorithms which attempt to find…

  • The Optimization game

    Optimizations are not trivial and theory is not enough. Let see an example of it at play.

    1 Comment
  • About AI and chatGPT especially

    Too many people think that AI will take our job. That's not entirely true.

  • Programming challenges at PDF Butler

    Here are the few challenges one can face at PDF Butler, two of them were from the past week. Challenge 1 You are given…

  • Buying a cake

    Once upon a time, Nole Ksum wanted to buy a cake. The bakery didn't like that idea and refused the deal.

  • The misunderstanding of Big Bang Theory

    You may skip that article altogether if you are unable to handle something a little controversial or don't know how to…

  • Regular polygons in shaders

    Some GL_ES to create regular polygons: // Author: Christiqn Baune // Title: Polygons #ifdef GL_ES precision mediump…

  • Slicing shapes

    Have you noticed that regular polygons and rectangles have a nice property when it comes to slicing them ? If the…

  • Small code problem

    Change the array values so it prints 1,2,3,4,5,6,7,8,9,10,11 in the console (easy): function changeArray(inArray) {…

Others also viewed

Explore content categories