Anthony Giniers

@antogyn

@aginiers

GraphQL :

Introduction

https://slides.com/antogyn/graphql-intro

GraphQL, c'est quoi ?

GraphQL est un langage de requête pour des données de type graphe

  • Débuté par Facebook en 2012
  • Open-source depuis 2015
  • Spécification et implémentations standards maintenues par Facebook : serveur Node.js, client React (Relay)
  • Écosystème jeune mais très actif
  • Utilisé par Facebook, GitHub, Twitter, Pinterest, The New York Times, Coursera, Shopify, Yelp, Dailymotion...

Alternative à REST

Falcor vs GraphQL ?

Adoption : GraphQL grand vainqueur

Un exemple simple

{
  user(id: 123) {
    id,
    name,
    profilePicture(size: SMALL) {
      uri
    }
  }
}
{
  "user": {
    "id": 123,
    "name": "Anthony Giniers",
    "profilePicture": {
      "uri": "http://xebia.fr/ag50.jpg",
    }
  }
}
  • Son id
  • Son nom
  • Sa photo de profil en taille "SMALL"
  • Mais uniquement l'uri

Pour le user d'id "123", on veut :

Les principes de base de GraphQL

- Hiérarchique

Une requête GraphQL est une liste hiérarchique de champs

{
  user(id: 123) {
    id,
    name,
    profilePicture(size: SMALL) {
      uri
    }
  }
}
{
  "user" : {
    "id": 123,
    "name": "Anthony Giniers",
    "profilePicture": {
      "uri": "http://xebia.fr/ag50.jpg",
    }
  }
}

→ Les données ont la même forme que la requête

→ Elles sont accessibles en une seule requête

- Hiérarchique

Je veux récupérer le dernier post de mon dernier ami

{
  me {
    friends(last: 1) {
      posts(last: 1) {
        body
      }
    }
  }
}

{
  "me": {
    "friends": [{
      "posts": [{
        "body": "poudre 2 perlimpinpin"
      }],
    }]
  }
}
  • GET /me/friends?last=1
  • GET /users/:id/posts?last=1

En REST ?

GET /me/friends/posts?last_friends=1&last_posts=1 ??

- Fortement typé

{
  user(id: 123) {
    id,
    name,
    profilePicture(size: SMALL) {
      uri
    }
  }
}
type Query {
  user(id: Int): User
}
  • Outils qui valident nos queries pendant le développement
  • Garanties sur la forme et la nature de la requête
  • Garanties sur la forme et la nature de la réponse
type User {
  id: Int!
  name: String
  profilePicture(size: Size): Media
}
type Media {
  uri: String
}
enum Size {
  SMALL
  LARGE
}
query {
  user(id: 123) {
    id,
    name,
    profilePicture(size: SMALL) {
      uri
    }
  }
}
{
  user(id: 123) {
    id,
    name,
    profilePicture(size: SMALL) {
      uri
    }
  }
}

- Requêtes construites par le client

Les spécifications sont encodées dans le client

Centré sur le produit (“product centric”)

GraphQL répond aux besoins des vues et des ingénieurs front-end/mobile

- Rétrocompatible

{
  user(id: 123) {
    id,
    name,
  }
}
type User {
  id: Int
  name: String @deprecated
  identity: Identity
}

type Identity {
  name: String
}
{
  user(id: 123) {
    id,
    identity {
      name
    }
  }
}
type User {
  id: Int
  name: String
}

- Introspectif

{
  "__schema": {
    "types": [
      {
        "name": "User",
        "fields": [
          {
            "name": "id",
            "type": {
              "name": "Int"
            }
          },
          {
            "name": "name",
            "type": {
              "name": "String"
            }
          },
          {
            "name": "profilePicture",
            "type": {
              "name": "Media"
            }
          }
        ]
      }
      ...
    ]
  }
}
type User {
  id: Int
  name: String
  profilePicture: Media
}
{
  __schema {
    types {
      name
      fields {
        name
        type {
          name
        }
      }
    }
  }
}

Le typage fort et cette capacité d'introspection permet l'intégration d'outils puissants

  • Génération d'interfaces fortement typées à partir d'un schéma GraphQL
  • Découverte et navigation d'API
  • Clients externes intelligents

→ GraphiQL

Par exemple :

Merci !

Questions ?