Slide 1

Slide 1 text

GraphQL @ Shopify Marc-André Giroux @__xuorig__

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

@__xuorig__ Les APIs REST sont

Slide 6

Slide 6 text

@__xuorig__ Sauf quand ils sont

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

@__xuorig__ SELECT * FROM /ENDPOINT

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

@__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/" ],

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

@__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/" ],

Slide 14

Slide 14 text

GraphQL

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

@__xuorig__ Une librairie ou un framework

Slide 17

Slide 17 text

@__xuorig__ Pas spécifique à un langage.

Slide 18

Slide 18 text

@__xuorig__ Langage de requête

Slide 19

Slide 19 text

@__xuorig__ &

Slide 20

Slide 20 text

@__xuorig__ Une Specification.

Slide 21

Slide 21 text

@__xuorig__ Un "Hello World" GraphQL

Slide 22

Slide 22 text

@__xuorig__ query { film { title } }

Slide 23

Slide 23 text

@__xuorig__ Anatomie d'une requête GraphQL.

Slide 24

Slide 24 text

@__xuorig__ query MyQuery { film { title } }

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

@__xuorig__ query MyQuery { film { title } } Field

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

@__xuorig__ query MyQuery { film { title } }

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

@__xuorig__ Query film title characters name

Slide 38

Slide 38 text

@__xuorig__ Le Type System.

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

@__xuorig__ Introspection.

Slide 44

Slide 44 text

@__xuorig__ { __schema { types { name } } }

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

@__xuorig__ GraphiQL

Slide 49

Slide 49 text

@__xuorig__

Slide 50

Slide 50 text

@__xuorig__ swapi-graphql-ruby.herokuapp.com

Slide 51

Slide 51 text

Mutations

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

Fragments

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

@__xuorig__ Gestion des versions.

Slide 59

Slide 59 text

@__xuorig__ Versioning Continuous Evolution

Slide 60

Slide 60 text

@__xuorig__ Sécurité?

Slide 61

Slide 61 text

@__xuorig__ • Maximum Depth • Query Complexity • Timeout

Slide 62

Slide 62 text

@__xuorig__ Je perds ma cache HTTP? ;(

Slide 63

Slide 63 text

@__xuorig__ POST /graphql

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

@__xuorig__ Requêtes persistées

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

@__xuorig__ GraphQL @ Shopify

Slide 71

Slide 71 text

@__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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

@__xuorig__ On prévient les "breaking changes"

Slide 76

Slide 76 text

@__xuorig__ Et on force les bonnes pratiques!

Slide 77

Slide 77 text

@__xuorig__ GraphQL est

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

@__xuorig__ Le serveur exprime les possibilités.

Slide 81

Slide 81 text

@__xuorig__ Les clients définissent leurs besoins.

Slide 82

Slide 82 text

@__xuorig__ separation of concerns!

Slide 83

Slide 83 text

@__xuorig__ DX

Slide 84

Slide 84 text

@__xuorig__ DX (Developer Experience)

Slide 85

Slide 85 text

@__xuorig__ On "ship" plus rapidement

Slide 86

Slide 86 text

@__xuorig__ Et tout le monde est heureux.

Slide 87

Slide 87 text

Merci! Marc-André Giroux @__xuorig__