Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sunny Tech 2018 - Rétrocompatibilité des API RE...

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →

Sunny Tech 2018 - Rétrocompatibilité des API REST avec GraphQL

Retour d'expérience sur la mise en place d'une Gateway GraphQL pour assurer la rétrocompatibilité de plusieurs API REST.

- Problématique de rétrocompatibilité des APIs
- Pourquoi GraphQL ?
- Quelques détails d'implémentations
- Points positifs / négatifs

Avatar for Thomas Girard

Thomas Girard

June 28, 2018

Other Decks in Technology

Transcript

  1. Gestion des versions / évolutions { "bike": { "name": "Vtt",

    "kms": 3450, "avg": 28.5 } } { "bike": { "name": "Vtt", "stats": { "kms": 3450, "avg": 28.5 } } } 3
  2. Agrégation des appels - Plusieurs appels pour une données complète

    - https://api.com/users/12354 - https://api.com/bikes/56 - https://api.com/bikes/56/stats - On récupère des choses inutiles - Gestion des erreurs - Modularité 5
  3. Schéma et Documentation - Swagger, Raml, OpenAPI - Postman, Restlet

    - Doc maison - Spring RestDoc - Jamais à jour - Difficilement jouable (playground) - Pas assez précise - Type (int, String, ...) - Null - Deprecated => Documentation from code 6
  4. GraphQL - https://graphql.github.io - Une spécification (Facebook) - Schema Definition

    Language - Langage de requêtes - Multiples implémentations (Js, Java, Scala, Ruby, Python, ...) - moteur d’exécution - Describe your data - Ask for what you want - Get predictable results 8
  5. Exemple Schema type Bike { name: String! kms: Int! avg:

    Float } type QueryType { bike(name: String): [Bike]! } schema { query: QueryType } Query { bike(name: "Vtt") { name kms avg } } Result { "bike": { "name": "Vtt", "kms": 3450, "avg": null } } 9
  6. Gestion des versions { "bike": { "name": "Vtt", "kms": 3450,

    "avg": 28.5 } } { "bike": { "name": "Vtt", "stats": { "kms": 3450, "avg": 28.5 } } } 10
  7. Gestion des versions Schema type Bike { name: String! stats:

    Stats } type Stats { kms: Int! avg: Float } type QueryType { bike(name: String): [Bike]! } schema { ... } Query { bike(name: "Vtt") { name stats { kms avg } } } Result { "bike": { "name": "Vtt", "stats": { "kms": 3450, "avg": null } } } 11
  8. Gestion des versions Schema type Bike { name: String! stats:

    Stats } type Stats { kms: Int! avg: Float } type QueryType { bike(name: String): [Bike]! } schema { ... } Query { bike(name: "Vtt") { name stats { kms avg } } } Result { "bike": { "name": "Vtt", "stats": { "kms": 3450, "avg": null }, } } kms: Int! @deprecated("stats.kms") avg: Float @deprecated("stats.avgs" kms avg "kms": 3450, "avg": null 12
  9. Gestion des versions Avantages : - Évolution du schéma -

    Compatibilité des anciens clients - Évolutions en douceurs - Documentation dans le code Inconvénients : - Maintien de la compatibilité côté serveur - Quand supprimer les @deprecated - Alourdi le schéma 13
  10. Fragmentation des APIs - Généralement, une API : - Une

    url - Un type (Bike, Stats, User) - Un micro-service query bike(name: String): [Bike]! query Fetcher<List<Bike>> { return listOf( Bike( "Vtt", Stats(3450, null) )) } type Fetcher<Bike>("kms") { env -> env.data.stats.kms } Fetcher<...> {} Fetcher<...> {} - Définition de Fetcher par query et type 15
  11. Agrégation des appels query { bike(name: "Vtt") { stats {

    kms } } } { "data": { "bike": { "stats": { "kms": 3450 } }, "stats": { "avg": null } } } }, "errors": [ { "message": "Error fetching stats", "locations": [ { "line": 8, "column": 6 } ] } ] } stats(id: 3) { avg } 16
  12. Introspection query query IntrospectionQuery { __schema { queryType { name

    } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description locations args { ...InputValue } } } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } } 18
  13. Conclusion Avantages : - Ça marche et bien - Evolution

    de schéma - Tests avec GraphiQL - Documentation - Plusieurs query => 1 requête - Imbrication des objets - Api REST + GraphQL - Moteur exécution != serveur Inconvénients : - Evolution du JSON des apis - Parse error - Développement en double - API + GraphQl - Coût de migration - Gestion des erreurs - N+1 requêtes - Temps de réponse 21