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

GraphQL à Shopify

GraphQL à Shopify

Marc-Andre Giroux

April 05, 2017
Tweet

More Decks by Marc-Andre Giroux

Other Decks in Programming

Transcript

  1. GraphQL @ Shopify
    Marc-André Giroux
    @__xuorig__

    View full-size slide

  2. @__xuorig__
    Les APIs REST sont

    View full-size slide

  3. @__xuorig__
    Sauf quand ils sont

    View full-size slide

  4. @__xuorig__
    Des allers-retours multiples...
    C'est pas idéal.

    View full-size slide

  5. @__xuorig__
    GET /people/1
    GET /planet/2
    GET /film/3

    View full-size slide

  6. @__xuorig__
    SELECT * FROM
    /ENDPOINT

    View full-size slide

  7. @__xuorig__
    GET /people/1
    { "person": { "name": "luke" } }

    View full-size slide

  8. @__xuorig__
    {
    "name": "Luke Skywalker",
    "height": "172",
    "mass": "77",
    "hair_color": "blond",
    "skin_color": "fair",
    "eye_color": "blue",
    "birth_year": "19BBY",
    "gender": "male",
    "homeworld": "http://swapi.co/api/
    planets/1/",
    "films": [
    "http://swapi.co/api/films/6/",
    "http://swapi.co/api/films/3/",
    "http://swapi.co/api/films/2/",
    "http://swapi.co/api/films/1/",
    "http://swapi.co/api/films/7/"
    ],

    View full-size slide

  9. @__xuorig__
    Qu'est-ce que nos clients
    utilisent vraiment?

    View full-size slide

  10. @__xuorig__
    {
    "name": "Luke Skywalker",
    "height": "172",
    "mass": "77",
    "hair_color": "blond",
    "skin_color": "fair",
    "eye_color": "blue",
    "birth_year": "19BBY",
    "gender": "male",
    "homeworld": "http://swapi.co/api/
    planets/1/",
    "films": [
    "http://swapi.co/api/films/6/",
    "http://swapi.co/api/films/3/",
    "http://swapi.co/api/films/2/",
    "http://swapi.co/api/films/1/",
    "http://swapi.co/api/films/7/"
    ],

    View full-size slide

  11. @__xuorig__
    Un type spécial de
    base de données.

    View full-size slide

  12. @__xuorig__
    Une
    librairie ou un framework

    View full-size slide

  13. @__xuorig__
    Pas spécifique à un langage.

    View full-size slide

  14. @__xuorig__
    Langage de requête

    View full-size slide

  15. @__xuorig__
    &

    View full-size slide

  16. @__xuorig__
    Une Specification.

    View full-size slide

  17. @__xuorig__
    Un "Hello World" GraphQL

    View full-size slide

  18. @__xuorig__
    query {
    film {
    title
    }
    }

    View full-size slide

  19. @__xuorig__
    Anatomie d'une requête GraphQL.

    View full-size slide

  20. @__xuorig__
    query MyQuery {
    film {
    title
    }
    }

    View full-size slide

  21. @__xuorig__
    query MyQuery {
    film {
    title
    }
    }
    Operation Type

    View full-size slide

  22. @__xuorig__
    query MyQuery {
    film {
    title
    }
    }
    Operation Name

    View full-size slide

  23. @__xuorig__
    query MyQuery {
    film {
    title
    }
    }
    Selection Set

    View full-size slide

  24. @__xuorig__
    query MyQuery {
    film {
    title
    }
    }
    Field

    View full-size slide

  25. @__xuorig__
    "data": {
    "film": {
    "title": "A New Hope"
    }
    }

    View full-size slide

  26. @__xuorig__
    query {
    film(id: "123") {
    title
    }
    }

    View full-size slide

  27. @__xuorig__
    query {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    }

    View full-size slide

  28. @__xuorig__
    "data": {
    "film": {
    "title": "A New Hope",
    "characters": [
    { "name": "Luke Skywalker" },
    { "name": "Princess Leia" }
    ]
    }
    }

    View full-size slide

  29. @__xuorig__
    query MyQuery { film { title } }

    View full-size slide

  30. @__xuorig__
    curl -X POST -d '{"query": "query MyQuery { film { title } }"}' http://
    mongraphql.com/api --header "Content-Type:application/json"

    View full-size slide

  31. @__xuorig__
    curl -X POST -d '{"query": "query MyQuery { film { title } }"}' http://
    mongraphql.com/api --header "Content-Type:application/json"

    View full-size slide

  32. @__xuorig__
    {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    }

    View full-size slide

  33. @__xuorig__
    Query
    film
    title
    characters
    name

    View full-size slide

  34. @__xuorig__
    Le Type System.

    View full-size slide

  35. @__xuorig__
    {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    }

    View full-size slide

  36. @__xuorig__
    {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    }
    type QueryRoot {
    film(id: ID!): Film
    }

    View full-size slide

  37. @__xuorig__
    {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    }
    type Film {
    title: String!
    characters: [Character!]!
    }

    View full-size slide

  38. @__xuorig__
    {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    }
    type Character {
    name: String!
    }

    View full-size slide

  39. @__xuorig__
    Introspection.

    View full-size slide

  40. @__xuorig__
    {
    __schema {
    types {
    name
    }
    }
    }

    View full-size slide

  41. @__xuorig__
    {
    __type(name: "Film") {
    name
    description
    }
    }

    View full-size slide

  42. @__xuorig__
    Introspection == Des clients
    avec des super pouvoirs!

    View full-size slide

  43. @__xuorig__
    • AutoSaisie
    • Validation côté client.
    • Intégration dans nos IDE.
    • Génération de code.

    View full-size slide

  44. @__xuorig__
    GraphiQL

    View full-size slide

  45. @__xuorig__
    swapi-graphql-ruby.herokuapp.com

    View full-size slide

  46. @__xuorig__
    mutation {
    addFilm(name: "StarWars 8") {
    title
    }
    }

    View full-size slide

  47. @__xuorig__
    query {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    bestRatedfilm {
    title
    characters {
    name
    }
    }
    }

    View full-size slide

  48. @__xuorig__
    query {
    film(id: "123") {
    title
    characters {
    name
    }
    }
    bestRatedfilm {
    title
    characters {
    name
    }
    }
    }

    View full-size slide

  49. @__xuorig__
    fragment filmFragment on Film {
    title
    characters {
    name
    }
    }

    View full-size slide

  50. @__xuorig__
    query {
    film(id: "123") {
    ...filmFragment
    }
    bestRatedfilm {
    ...filmFragment
    }
    }
    fragment filmFragment on Film {
    title
    characters {
    name
    }
    }

    View full-size slide

  51. @__xuorig__
    Gestion des versions.

    View full-size slide

  52. @__xuorig__
    Versioning
    Continuous Evolution

    View full-size slide

  53. @__xuorig__
    Sécurité?

    View full-size slide

  54. @__xuorig__
    • Maximum Depth
    • Query Complexity
    • Timeout

    View full-size slide

  55. @__xuorig__
    Je perds ma cache HTTP? ;(

    View full-size slide

  56. @__xuorig__
    POST /graphql

    View full-size slide

  57. @__xuorig__
    • Cache côté client
    • Requête persistées

    View full-size slide

  58. @__xuorig__
    Requêtes persistées

    View full-size slide

  59. @__xuorig__
    Requêtes persistées
    query MyQuery { film { title } }
    Yo. c'est possible que j'utilise
    cette requête plus tard!

    View full-size slide

  60. @__xuorig__
    Requêtes persistées
    Cool pas de prob, envoie moi
    "abcd" et je l'exécuterai pour toi

    View full-size slide

  61. @__xuorig__
    Requêtes persistées
    J'ai besoin de "abcd"!

    View full-size slide

  62. @__xuorig__
    Requêtes persistées
    "data": {
    "film": {
    "title": "A New Hope"
    }
    }

    View full-size slide

  63. @__xuorig__
    GraphQL @ Shopify

    View full-size slide

  64. @__xuorig__
    Définir les types
    module GraphApi
    class Shop < GraphApi::ObjectType
    field :name, :string
    field :currency, :string, null: false
    field :products, [Product],
    resolve: ->(shop, _, _) { shop.products }
    end
    end

    View full-size slide

  65. @__xuorig__
    type Shop {
    name: String
    currency: String!
    products: [Product!]
    }

    View full-size slide

  66. @__xuorig__
    • Client Side Cache
    • Persisted Queries
    Le Schema est "Checked In"

    View full-size slide

  67. @__xuorig__
    Et doit toujours être régénéré!

    View full-size slide

  68. @__xuorig__
    On prévient les "breaking changes"

    View full-size slide

  69. @__xuorig__
    Et on force les bonnes pratiques!

    View full-size slide

  70. @__xuorig__
    GraphQL est

    View full-size slide

  71. @__xuorig__
    A Un seul allez-retour
    pour récupérer tout
    se qu'un client à
    besoin.

    View full-size slide

  72. @__xuorig__
    Declaratif et predictible.
    (plus besoin de notre fameux SELECT *)

    View full-size slide

  73. @__xuorig__
    Le serveur exprime les
    possibilités.

    View full-size slide

  74. @__xuorig__
    Les clients définissent leurs
    besoins.

    View full-size slide

  75. @__xuorig__
    separation of concerns!

    View full-size slide

  76. @__xuorig__
    DX

    View full-size slide

  77. @__xuorig__
    DX (Developer Experience)

    View full-size slide

  78. @__xuorig__
    On "ship" plus rapidement

    View full-size slide

  79. @__xuorig__
    Et tout le monde est heureux.

    View full-size slide

  80. Merci!
    Marc-André Giroux
    @__xuorig__

    View full-size slide