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

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. @anapbastos ANA PORTELLO github.com/anabastos anabastos.me Full-Stack Developer

  2. JSLADIES fb.com/jsladiesbr twitter.com/jsladiessp meetup.com/JsLadies-BR/

  3. GRAPHQL & NODE.JS Construindo API's robustas e escaláveis com

  4. VAMOS FALAR SOBRE REST

  5. O QUE UMA RESTFULL API?

  6. Cliente Servidor HTTP URI

  7. REQUISIÇÃO Cabeçalho Corpo RESPOSTA Cabeçalho Corpo

  8. GET POST PUT DELETE PATCH HEAD TRACE OPTIONS

  9. Representational State Transfer

  10. EXEMPLO DE REST

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

    { name: “Marley”, age: 10, breed: “Labrador” }, ] 200 OK GET endpoint /dogs
  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” }
  13. ATÉ AI TUDO BEM...

  14. animals/cats animals/dogs animals/dogs/:id animals/dogs/:id/flea animals/dogs/:id/flea/:id animals/dogs/breed/:id animals/dogs/:id/relatory animals/dogs/:id/upload animals/dogs/:id/album/photo/comment/:id

  15. COM A ESCALABILIDADE DO PROJETO MUITOS ENDPOINTS PRECISAM SER CRIADOS

  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
  17. None
  18. TODOS OS DADOS SÃO USADOS?

  19. TRÁFEGO É CUSTO

  20. GET animals/cats?fields=name,breed GET animals/dogs?fields=name,breed GET animals/dogs/:id?fields=name,age, bio GET animals/dogs/:id?fields=owner GET

    animals/dogs/:id/?fields=name,bio.personality
  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”, } …
  22. NECESSIDADE DE VÁRIAS REQUISIÇÕES

  23. • 1 REQUEST P/ DOG E 10 PARA CADA OWNER

    • 1 REQUEST DANDO FETCH EM TODOS OS 10 STATUS DO DOG
  24. NO SITE APARECE OS 10 ULTIMOS STATUS NO APP IOS

    APARECE OS 5 ULTIMOS STATUS NO APP ANDROID APARECE OS 4 ULTIMOS
  25. PRECISO DE MAIS ENDPOINTS PRA MINHA API

  26. O CLIENT NÃO ESCOLHE O TIPO DE DADO QUE QUER

    VISUALIZAR
  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
  28. “What you want is what you get”

  29. O QUE E GRAPHQL?

  30. QUERY LANGUAGE

  31. FACILITAR A CONSULTA DE DADOS

  32. GRAPHQL desenvolvida em 2012 no FACEBOOK

  33. OPEN SOURCE em 2015

  34. JAVASCRIPT PYTHON RUBY CLOJURE PHP JAVA C# GO SCALA ERLANG

    ELIXIR
  35. POST endpoint graphql/

  36. EXPRESSIVO

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

    quero :) } POST endpoint graphql/
  38. CLIENT SERVER GRAPHQL DATA RESOLVE BODY JSON

  39. QUERIES ou MUTATIONS

  40. QUERIES LÊEM MUTATIONS ESCREVEM

  41. QUERIES

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

    { ‘name’: “Bob”, } ] CORPO { dogs { name } }
  43. RESPONSE { ‘name’: “Marley”, ‘age’: 11, ‘breed’: “Labrador” } CORPO

    { dogs(1){ name age breed } }
  44. HIERARQUICO

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

    { ‘name’: “Jenny”, } ] } REQUEST { dogs(1){ name owners { name } } }
  46. ARGUMENTOS

  47. RESPONSE { ‘name’: “Marley”, } REQUEST { dog: { breed(name:

    “Labrador”){ name } } }
  48. FILTER

  49. RESPONSE [{...},{...},{...},{...},{...} ,{...},{...},{...},{...},{...}] REQUEST { dog: { status( first: 10,

    orderBy: { field: CREATED_AT, direction: DESC }) } }
  50. ALIAS

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

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

  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’ }
  54. DIRETIVAS

  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 }
  56. RETORNA O QUE PRECISAMOS

  57. MUTATIONS

  58. POST PATCH PUT

  59. VOCE CRIA A SUA AÇAO

  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!” } }
  61. REQUEST mutation deleteCommentaryForDog( $dog: Dog!, $comment = Comment!) { deleteCommentary

    (dog: $dog, comment: $comment){ stars text } } VARIABLE { dog: ‘Marley’ comment: { stars: 5 text: “So cuteee!” } }
  62. inactivateComment removeComment pinComment editComment flagComment

  63. COMO FAÇO NO NODE?

  64. import graphql from ‘<insiraSeuFramework>-graphql’

  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)
  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)
  67. FORTEMENTE TIPADO

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

    price: !Float basket: [String] tax(value: Int): Float } `}
  69. OBJECT TYPES

  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] }
  71. type Boleto { id: ID value: Float CPF: String expiration:

    Date status:Status } enum Status { PAID WAITING }
  72. Type schemes com tipos de dados dentro de tipos de

    dados dentro de tipos de dados
  73. JSON só que tipado

  74. FUNÇOES RESOLVER

  75. CADA END POINT TEM UMA FUNÇAO RESOLVER QUE LIDA COM

    OS DADOS
  76. const schema = buildSchema {` type Billing { price: !Float

    tax(value: Int): Float } `} const root = { price = () => getPrice() tax = args => getPrice() * 0.1 }
  77. GRAPHiQL

  78. MSGS CLARAS SYNTAX HIGHLIGHT AUTO COMPLETE AUTO DOCUMENTAÇÃO

  79. DEMO GRAPHIQL

  80. MODELAGEM

  81. GRAFOS

  82. user { _id address } email { userId content data

    usersSent { _id name } }
  83. EMAIL USER Ponto final?

  84. EMAIL USER user { _id address email { userId content

    data usersSent { _id name } }
  85. EMAIL USER USER USER EMAIL EMAIL USER USER USER O

    único limite p/ percorrer um grafo são os próprios dados
  86. DEMO

  87. REST MORREU?

  88. NÃO.

  89. MOTIVOS P/ USAR GRAPHQL EM PRODUÇÃO

  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.
  91. MOTIVOS P/ NÃO USAR GRAPHQL

  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.
  93. GRAPHQL NÃO VAI RESOLVER SEUS PROBLEMAS DE DESIGN DE API

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

    mandar mal provendo uma GRAPHQL” Arnaud Lauret
  95. GOSTEI

  96. NÃO PENSE DE FORMA REST

  97. PROCURE SOBRE DATA LOADER

  98. APOLLO OU RELAY

  99. ABUSE DE FILTROS

  100. ACHEI OVERKILL

  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”
  102. GRAPHQL É TOP

  103. howtographql.com/basics/ http://graphql.org/graphql-js/ http://igorluiz.me/videos/ fun fun function graphql series https://t.me/reactjs_br

  104. meetup.com/ReactJS-SP/ meetup.com/reactbh/ react-brasil.github.io/react-brasil-slack/

  105. OBRIGADA :) speakerdeck.com/anabastos

  106. DÚVIDAS? saq@anabastos.me speakerdeck.com/anabastos