DEVFEST BH - Construindo API's robustas e escaláveis com Graphql e Node.js

DEVFEST BH - Construindo API's robustas e escaláveis com Graphql e Node.js

Apresentação feita no DEVFEST BH 2017 :)

Fcfcfbcdbe8543b6d76c7566d6e1693c?s=128

Ana Luiza Portello

November 18, 2017
Tweet

Transcript

  1. 11.

    RESPOSTA [ { name: “Lili”, age: 3, breed: “Vira-lata”, },

    { name: “Marley”, age: 10, breed: “Labrador” }, ] 200 OK GET endpoint /dogs
  2. 12.

    RESPOSTA [ { name: “Lili”, age: 3, breed: “Vira-lata”, },

    { name: “Marley”, age: 10, breed: “Labrador” }, { name: “Bob”, age: 5, breed: “Shiba Inu” } ] 200 OK POST endpoint /dogs CORPO DA REQ { name: “Bob”, age: 5, breed: “Shiba Inu” }
  3. 16.

    RESPONSE { name: “Marley”, age: 10, gender: “Male”, color: {

    main: “Caramel”, spots: … } breed: {…} owner: [{…},{…}] registration: 1235382 body: { height: 1m, weight: 55kg }, allergies: [‘Strawberries’] bio : { personality: “Good Boy”, agressiveLvl: 0 } mom: …, bothers: [{…}, {…}, {…},{…}] … GET endpoint /dogs
  4. 17.
  5. 21.

    // quero pegar os 10 ultimos status do dog no

    meu site GET animals/dog/1 RESPONSE { name: “Marley”, … status: [{…},{…}…] … } // pegar cada status pelo id GET status/1 GET status/2 GET status/3 ... { … _id: 1 status: “Happy”, } … { … _id: 2 name: “Sleeping”, } …
  6. 23.

    • 1 REQUEST P/ DOG E 10 PARA CADA OWNER

    • 1 REQUEST DANDO FETCH EM TODOS OS 10 STATUS DO DOG
  7. 24.

    NO SITE APARECE OS 10 ULTIMOS STATUS NO APP IOS

    APARECE OS 5 ULTIMOS STATUS NO APP ANDROID APARECE OS 4 ULTIMOS
  8. 27.

    “Ficamos frustrados com as diferenças entre os dados que queríamos

    e as requisições que eram necessárias para obtê-los” Lee Byron
  9. 37.

    CORPO DA REQUEST { Os dados explícitos do que eu

    quero :) } POST endpoint graphql/
  10. 41.
  11. 42.

    RESPONSE [ { ‘name’: “Marley”, }, { ‘name’: “Lili”, },

    { ‘name’: “Bob”, } ] CORPO { dogs { name } }
  12. 45.

    RESPONSE { ‘name’: “Marley”, ‘owners’: [ { ‘name’: “John”, },

    { ‘name’: “Jenny”, } ] } REQUEST { dogs(1){ name owners { name } } }
  13. 48.
  14. 50.
  15. 51.

    RESPONSE { ‘labradorDog’ { ‘name’: ‘Marley’ } ‘shibaInuDog’{ ‘name’: ‘Bob’

    } } REQUEST { labradorDog: dog(breed: ‘Labrador’){ name } shibaInuDog: dog(breed: ‘Shiba Inu’){ name } }
  16. 52.
  17. 53.

    RESPONSE { ‘name’: ‘John’, ‘payments’: [ { ‘value’: 100,55 },

    { ‘value’: 120,55 } ] } REQUEST query ownerPayments( $cpf: String) { owner(cpf: $cpf): { name payments { value } } } VARIABLE { cpf: ‘12332132155’ }
  18. 54.
  19. 55.

    RESPONSE { ‘name’: ‘Bob’, ‘age’: 3 ‘breed’: ‘Shiba Inu’ }

    REQUEST query DogBio($register: String, $withPhotos = Boolean) { dog(register: $register): { name, age, breed, photos @include(if: $withPhotos) } } VARIABLE { ‘register’: ‘123475832’ ‘withPhotos’: false }
  20. 57.
  21. 60.

    RESPONSE { ‘createCommentary’ { ‘stars’: 5 ‘commentary’: “So cuteee!” }

    } REQUEST mutation createCommentaryForDog( $dog: Dog!, $comment = Comment!) { createCommentary (dog: $dog, comment: $comment){ stars text } } VARIABLE { dog: ‘Marley’ comment: { stars: 5 text: “So cuteee!” } }
  22. 61.

    REQUEST mutation deleteCommentaryForDog( $dog: Dog!, $comment = Comment!) { deleteCommentary

    (dog: $dog, comment: $comment){ stars text } } VARIABLE { dog: ‘Marley’ comment: { stars: 5 text: “So cuteee!” } }
  23. 65.

    import express from ‘express’ import graphql from ‘express-graphql’ import rootSchema

    from ‘./src/app’ const app = express() app.use(‘/graphql’, graphqlHTTP({ schema: rootSchema, rootValue: root graphiql: true, })) app.listen(4000)
  24. 66.

    import koa from ‘koa’ import graphql from ‘koa-graphql’ import mount

    from ‘koa-mount’ import rootSchema from ‘./src/app’ const app =koa() app.use(mount(‘/graphql’, graphqlHTTP({ schema: rootSchema, rootValue: root graphiql: true, }))) app.listen(4000)
  25. 68.

    const schema = buildSchema {` type Query { paid: Boolean

    price: !Float basket: [String] tax(value: Int): Float } `}
  26. 70.

    type Talk { id: ID title: String description: String published:

    Date speaker: Speaker event: Event } type Speaker { id: ID firstName: String lastName: String talks: [Talks] } type Event { id: ID name: String location: String talks: [Talks] }
  27. 71.

    type Boleto { id: ID value: Float CPF: String expiration:

    Date status:Status } enum Status { PAID WAITING }
  28. 72.
  29. 76.

    const schema = buildSchema {` type Billing { price: !Float

    tax(value: Int): Float } `} const root = { price = () => getPrice() tax = args => getPrice() * 0.1 }
  30. 77.
  31. 80.
  32. 81.
  33. 84.
  34. 85.

    EMAIL USER USER USER EMAIL EMAIL USER USER USER O

    único limite p/ percorrer um grafo são os próprios dados
  35. 86.
  36. 88.
  37. 90.

    • DIFERENTES CLIENTES: Há a necessidade de criar várias versões

    de dados diferentes para múltiplos clientes. • PREPARAR DADOS: Há muito esforço do server preparar os dados e do cliente para parsea-los. • LINKAR DADOS: Quando os dados mudam com muita frequência e precisam estar linkados sempre.
  38. 92.

    • HYPE: Minha empresa gosta do stack do facebook e

    todo mundo acha mo hype. • ODEIO HTTP(Consistencia, Caching, Status Code). • TOO NORMALIZED: Tenho muitas relações no meu banco de dados.
  39. 94.

    “Se você manda mal provendo uma API REST, você VAI

    mandar mal provendo uma GRAPHQL” Arnaud Lauret
  40. 95.
  41. 101.

    • Tome cuidado com a quantia de bytes que você

    trafega. • Considere que o client escolha o que ele quer receber com argumentos em query. • Desenvolva interfaces mais declarativas • Considere um JSON API. “GET dog/1?include=status”