Une introduction à GraphQL

GraphQL est un langage de requête pour votre API et un ensemble d'exécutables côté serveur (implémentés dans divers langages de backend) pour exécuter des requêtes

Qu'est-ce que GraphQL

GraphQL est la nouvelle frontière des API (Interfaces de programmation d'application) conception, et comment nous les construisons et les consommons.

C'est un langage de requête et un ensemble d'exécutables côté serveur (implémentés dans divers langages de backend) pour exécuter des requêtes. Ce n'est pas lié à une technologie spécifique, mais vous pouvez l'implémenter dans n'importe quelle langue.

C'est une méthodologie quientre directement en concurrence avec REST(Transfert d'état de représentation) API, tout comme REST en concurrence avecSAVONd'abord.

Et comme nous le verrons, c'est très différent de REST. Cela crée une toute nouvelle dimension pour la conception d'API.

GraphQL étaitdéveloppé chez Facebook, comme de nombreuses technologies qui secouent le monde JavaScript ces derniers temps, commeRéagiret React Native, et c'était publiquementlaunched in 2015- bien que Facebook l'ait utilisé en interne pendant quelques années auparavant.

De nombreuses grandes entreprises adoptent GraphQL à côté de Facebook, notamment GitHub, Pinterest, Twitter, Sky, The New York Times, Shopify, Yelp et des milliers d'autres.

J'ai été en contact avec GraphQL pour la première fois lorsque GitHub a décidé d'implémenter la v4 de leur API en utilisant cette technologie, et j'ai rejoint leur programme bêta. C'est là que j'ai découvert que cela changeait la donne à bien des égards.

Comment ça fonctionne

GraphQL expose un seul point de terminaisondepuis votre serveur.

Tuenvoyer une requête à ce point de terminaisonen utilisant une syntaxe spéciale du langage de requête. Cette requête estjuste une corde.

Le serveur répond à une requête en fournissant un objet JSON.

Voyons un premier exemple d'une telle requête. Cette requête obtient le nom d'une personne avecid=1:

GET /graphql?query={ person(id: "1") { name } }

or:

{
  person(id: "1") {
    name
  }
}

We’ll get this JSON response back:

{
  "name": "Tony"
}

Let’s add a bit more complexity: we get the name of the person, and the city where the person lives, by extracting it from the address object. We don’t care about other details of the address, and the server does not return them back to us because we didn’t ask for them:

GET /graphql?query={ person(id: "1") { name, address { city } } }

or

{
  person(id: "1") {
    name
    address {
      city
    }
  }
}

This is what we get back:

{
  "name": "Tony",
  "address": {
    "city": "York"
  }
}

As you can see the data we get is basically the same structure of the request we sent, filled with values that were fetched.

GraphQL Queries

In this section you’ll learn how is a GraphQL query composed.

The concepts I’ll introduce are

  • fields and arguments
  • aliases
  • fragments

Fields and arguments

Take this simple GraphQL query:

{
  person(id: "1") {
    name
  }
}

In this query you see 2 fields, person and name, and 1 argument.

The field person returns an Object which has another field in it, a String.

The argument allows us to specify which person we want to reference. We pass an id, but we could as well pass a name argument, if the API we talk to has the option to find a person by name.

Arguments are not limited to any particular field. We could have a friends field in person that lists the friends of that person, and it could have a limit argument, to specify how many we want the API to return:

{
  person(id: "1") {
    name
    friends(limit: 100)
  }
}

Aliases

You can ask the API to return a field with a different name. For example here you request the name field, but you want it returned as fullname:

{
  owner: person(id: "1") {
    fullname: name
  }
}

will return

{
  "data": {
    "owner": {
      "fullname": "Tony"
    }
  }
}

This feature, beside creating more ad-hoc naming for your client code, in case you need, is the only thing that can make the query work if you need to reference the same endpoint 2 times in the same query:

{
  owner: person(id: "1") {
    fullname: name
  }
  first_employee: person(id: "2") {
    fullname: name
  }
}

Fragments

In the above query we replicated the person structure. Fragments allow us to specify the structure just once (a very useful thing when you have many similar fields):

{
  owner: person(id: "1") {
    ...personFields
  }
  first_employee: person(id: "2") {
    ...personFields
  }
}

fragment personFields on person { fullname: name }

GraphQL Variables

More complex GraphQL queries need to use variables, a way to dynamically specify a value that is used inside a query.

In this case we added the person id as a string inside the query:

{
  owner: person(id: "1") {
    fullname: name
  }
}

The id will most probably change dynamically in our program, so we need a way to pass it, and not with string interpolation.

With variables, the same query can be written as this:

query GetOwner($id: String) {
  owner: person(id: $id) {
    fullname: name
  }
}

{ “id”: “1” }

In this snippet we have assigned the GetOwner name to our query. Think of it as named functions, while previously you had an anonymous function. Named queries are useful when you have lots of queries in your application.

The query definition with the variables looks like a function definition, and it works in an equivalent way.

Making variables required

Appending a ! to the type:

query GetOwner($id: String!)

instead of $id: String will make the $id variable required.

Specifying a default value for a variable

You can specify a default value using this syntax:

query GetOwner($id: String = "1")

GraphQL Directives

Directives let you include or exclude a field if a variable is true or false.

query GetPerson($id: String) {
  person(id: $id) {
    fullname: name,
    address: @include(if: $getAddress) {
      city
      street
      country
    }
  }
}

{ “id”: “1”, “getAddress”: false }

In this case if getAddress variable we pass is true, we also get the address field, otherwise not.

We have 2 directives available: include, which we have just seen (includes if true), and skip, which is the opposite (skips if true)

@include(if: Boolean)

query GetPerson($id: String) {
  person(id: $id) {
    fullname: name,
    address: @include(if: $getAddress) {
      city
      street
      country
    }
  }
}

{ “id”: “1”, “getAddress”: false }

@skip(if: Boolean)

query GetPerson($id: String) {
  person(id: $id) {
    fullname: name,
    address: @skip(if: $excludeAddress) {
      city
      street
      country
    }
  }
}

{ “id”: “1”, “excludeAddress”: false }


More graphql tutorials: