Anthony Giniers
@antogyn
@aginiers
GraphQL part 1 :
Introduction
https://slides.com/antogyn/graphql
Bastien Chares
@charesbast
@papybastou
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, Pinterest, Coursera, Shopify, Yelp...
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 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”)
Le langage de requête répond aux besoins des vues et des ingénieurs front-ends
- 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 :
Utilisons le GraphiQL de GitHub !
https://developer.github.com/early-access/graphql/explorer/
https://developer.github.com/v4/explorer/
- Récupérer mes 5 derniers repositories publics
- Afficher leur dernière pull request
- Ajouter un commentaire à une pull request
Queries vs Mutations
Le verbe http n'a pas d'importance avec GraphQL (généralement, on utilise du POST)
Cependant, on distingue les Queries des Mutations (équivalents de Query/Command du CQRS)
type Query {
user(id: String!): User
}
type Mutation {
createUser(name: String!): User
}
query {
user(id: 123) {
id,
name
}
}
mutation {
createUser(name: "toto") {
id,
name
}
}
mutation createToto {
createUser(username: "toto") {
id
}
}
mutation createAnyUser($username: String!) {
createUser(username: $username) {
id
}
}
{
"username": "toto"
}
Variables
=> Requêtes statiques réutilisables
Variable $username
de type String!
➡ /users/antogyn/repos?sort=pushed&direction=desc&page=1
Et en REST ?
https://api.github.com/
Récupérer les 5 derniers repos :
La dernière pull request :
➡ /repos/antogyn/xke-graphql-github/pulls?page=1
Rajouter un commentaire :
➡ /repos/antogyn/xke-graphql-github/issues/3/comments
x5 !!!
Quand utiliser GraphQL ?
- Des données en graphe
- API consommée par du front
- Besoin de limiter le nombre de connections côté client (=mobile)
- Utilisation d'une lib client reconnue (notamment à cause du cache)
- Régulièrement des nouveaux besoins front
Bonus points :
Pain points
- Authentification
- File upload
Et c'est compliqué à mettre en place ?
Non.
(petit temps d'adaptation, mais le gain de temps et de confort en vaut la peine)
Merci !
Questions ?
GraphQL partie 1
By antogyn
GraphQL partie 1
XKE 09/05/2017
- 1,088