Anthony Giniers

@antogyn

@aginiers

Construire une architecture GraphQL distribuée avec Apollo Federation (todo)

https://slides.com/antogyn/apollo-federation

  1. Principes de base de GraphQL

  2. Implémentations habituelles de GraphQL dans une architecture distribuée

  3. Live Coding d'Apollo Federation

Les principes de base de GraphQL

GraphQL, c'est quoi ?

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

Alternative à REST

- Hiérarchique

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

{
  user(id: "123") {
    id
    name
    company {
      name
      website
    }
  }
}
{
  "user" : {
    "id": "123",
    "name": "Anthony Giniers",
    "company": {
      "name": "Swan",
      "website": "https://www.swan.io"
    }
  }
}

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

→ Elles sont accessibles en une seule requête

- Fortement typé

type Query {
  user(id: String!): User
}
  • Outils qui valident nos queries pendant le développement (+ autocomplétion)
  • Garanties sur la forme et la nature de la réponse
  • Documentation
type User {
  id: String!
  name: String
  company: Company
}
type Company {
  name: String!
  website: String
}
{
  user(id: "123") {
    id
    name
    company {
      name
      website
    }
  }
}

- Requêtes construites par le client

Les spécifications sont encodées dans le client

Centré sur le produit (“product centric”)

- Rétrocompatible

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

type Identity {
  name: String
}
{
  user(id: "123") {
    id
    identity {
      name
    }
  }
}
type User {
  id: String!
  name: String
}

- Introspectif

{
  "__schema": {
    "types": [
      {
        "name": "User",
        "fields": [
          {
            "name": "id",
            "type": {
              "name": "String"
            }
          },
          {
            "name": "name",
            "type": {
              "name": "String"
            }
          }
        ]
      }
      ...
    ]
  }
}
type User {
  id: String
  name: String
}
{
  __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 :

Implémentations habituelles de GraphQL dans une architecture distribuée

- Services non GraphQL + Gateway GraphQL

IAM

Payment

Gateway

REST, gRPC, ...

REST, gRPC, ...

Les +

  • Chaque service garde son style d'architecture

Les -

  • Gateway intelligente et complexe 
  • Double travail d'implémentation et de documentation
type User {
  id: String!
  name: String
}

- Services GraphQL + Schema Stitching (legacy)

IAM

Payment

Gateway

Les +

  • Une seule techno (graphql)
  • Gateway simple pour les cas simples 

Les -

  • La gateway reste intelligente pour des cas complexes
type User {
  id: String!
  name: String
  payments: [Payment]
}
type Payment {
  value: String
  user: User
}

Comment lier Payment et User ??

{
  user("123") {  <=== récupéré depuis IAM
    payments { <=== récupéré depuis Payment
      user { <=== récupéré depuis IAM
        name
      }
    }
  }
}

- Services GraphQL + Apollo Federation

IAM

Payment

Gateway

type User {
  id: String!
  name: String
  payments: [Payment]
}
type Payment {
  value: String
  user: User
}

Comment lier Payment et User ??

- Services GraphQL + Apollo Federation

type User {
  id: String!
  name: String
  payments: [Payment] <== que vient faire payment ici ?
}
type Payment {
  value: String
  user: User
}

IAM

Payment

type User {
  id: String!
  name: String
}
type Payment {
  value: String
  user: User
}

extend type User {
  payments: [Payment]
}
type Payment {
  value: String
  user: User
}

extend type User @key(fields: "id") {
  id: String! @external
  payments: [Payment]
}
type User @key(fields: "id") {
  id: String!
  name: String
}


Live Coding avec Apollo Federation

Merci !

Questions ?