O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

PHP Community Summit - Do REST ao GraphQL com PHP

1.007 visualizações

Publicada em

Apresentação ministrada no PHP Community Summit, promovido pela Locaweb, no dia 01/09/2017.

Publicada em: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui

PHP Community Summit - Do REST ao GraphQL com PHP

  1. 1. Do REST ao GraphQL com PHP BRUNO NEVES brunonm@gmail.com @brunodasneves
  2. 2. Roteiro REST & GraphQL História Especificação / Linguagem PHP
  3. 3. Newsfeed App
  4. 4. GET /news/1 { "id": "1", "user_id": "57", "media_id": "20", "title": "Joesley rompe com Tony Ramos", "excerpt": "Mussum, Ipsum, cacilds", "text": "Mussum, Ipsum, cacilds vidis litro abertis...", "created_at": "1495928417", "status": "PUBLISHED" }
  5. 5. GET /users/57 { "id": "57", "name": "Mad Max", "email": "madmax@locaweb.com", "role": "WRITER", "created_at": "1495928417" }
  6. 6. GET /medias/20 { "id": "20", "type": "image/jpeg", "filename": "friboi.jpg", "size": "204800", "url": "http://news/media/65815736d29cc094a2d784c338066029" }
  7. 7. GET /news/1/comments [ { "id": "25", "news_id": "1", "text": "Não sou faixa preta cumpadi, sou preto inteiris.", "created_at": "1495928417", "author": { "name": "Nissim Ourfali", "email": "nissimourfali@locaweb.com" } }, //... a lot of comments ]
  8. 8. /news/1 /users/57 //... /medias/20 /news/1/comments
  9. 9. Como seria pedir SOMENTE o necessário e receber EXATAMENTE o que pediu de UMA SÓ VEZ?
  10. 10. { news(id: 1) { title, text, created_at, media { url }, user { name }, comments { text, author { name } } } }
  11. 11. { news(id: 1) { title, text, created_at, media { url }, user { name }, comments { text, author { name } } } } [ { "title": "Joesley rompe com Tony Ramos", "text": "Mussum, Ipsum, cacilds vidis...", "created_at": "1495928417", "media": { "url":"http://news/media/65815736... }, "user": { "name": "Mad Max" }, "comments": [ //... ] } ]
  12. 12. História Fevereiro 2012 Protótipo SuperGraph
  13. 13. História Desenvolvimento inicial
  14. 14. História Facebook Newsfeed API para iOS Agosto 2012
  15. 15. História Evolução
  16. 16. História Primeira aparição pública Janeiro 2015
  17. 17. História Refactoring
  18. 18. História Open Source Julho 2015
  19. 19. História Feedback da comunidade
  20. 20. História Release Setembro 2016
  21. 21. GraphQL.org
  22. 22. $ composer require webonyx/graphql-php http://webonyx.github.io/graphql-php/
  23. 23. Schema
  24. 24. Descreve os dados
  25. 25. Cardápio
  26. 26. $userType = new ObjectType([ 'name' => 'User', 'fields' => [ 'id' => Type::nonNull(Type::id()), 'name' => Type::nonNull(Type::string()), 'email' => Type::nonNull(Type::string()), 'role' => Type::nonNull(Type::string()), 'created_at' => Type::nonNull(Type::int()) ] ]);
  27. 27. $mediaType = new ObjectType([ 'name' => 'Media', 'fields' => [ 'id' => Type::nonNull(Type::id()), 'type' => Type::nonNull(Type::string()), 'filename' => Type::nonNull(Type::string()), 'size' => Type::nonNull(Type::string()), 'url' => Type::nonNull(Type::string()) ] ]);
  28. 28. $commentType = new ObjectType([ 'name' => 'Comment', 'fields' => [ 'id' => Type::nonNull(Type::id()), 'text' => Type::nonNull(Type::string()), 'created_at' => Type::nonNull(Type::int()), 'author' => Type::nonNull(new ObjectType([ 'name' => 'Author', 'fields' => [ 'name' => Type::string(), 'email' => Type::string() ] ])) ] ]);
  29. 29. $newsType = new ObjectType([ 'name' => 'News', 'fields' => [ 'id' => Type::nonNull(Type::id()), 'user' => Type::nonNull($userType), 'media' => $mediaType, 'title' => Type::nonNull(Type::string()), 'excerpt' => Type::string(), 'text' => Type::nonNull(Type::string()), 'created_at' => Type::nonNull(Type::int()), 'status' => Type::nonNull(Type::string()), 'comments' => Type::listOf($commentType) ] ]);
  30. 30. Um serviço GraphQL é composto por TYPES, que por sua vez são compostos por FIELDS
  31. 31. Types Int Float Boolean String ID Object
  32. 32. Modificadores List Non-Null
  33. 33. Root Types
  34. 34. Type System
  35. 35. São tipos especiais de objetos que ficam na raiz do schema
  36. 36. Enquanto a MUTATION é opcional, a QUERY deve estar presente em todo schema GraphQL
  37. 37. $mutationType = new ObjectType([ 'name' => 'Mutation', 'fields' => [ 'registerUser' => $registerUserMutation, 'registerComment' => $registerCommentMutation, 'reportContent' => $reportContentMutation ] ]); $queryType = new ObjectType([ 'name' => 'Query', 'fields' => [ 'news' => $newsQuery, 'categories' => $categoriesQuery, 'users' => $usersQuery ], ]);
  38. 38. $schema = new Schema([ 'query' => $queryType, 'mutation' => $mutationType ]);
  39. 39. Queries & Mutations
  40. 40. QUERY são operações de consulta no serviço
  41. 41. query{ news(id: 1) { title, text, created_at, media { url }, user { name }, comments { text, author { name } } } } $newsQuery = [ 'type' => Type::listOf($newsType), 'args' => [ 'id' => Type::id() ], 'resolve' => function ($root, $args) { if ($args['id'] ?? false) { return NewsRepository::findBy( ['id' => $args['id']] ); } return NewsRepository::findAll(); } ];
  42. 42. MUTATION são operações que modificam os dados no serviço
  43. 43. Nomenclatura imperativa
  44. 44. $registerUserMutation = [ 'type' => $userType, 'args' => [ 'name' => Type::nonNull(Type::string()), 'email' => Type::nonNull(Type::string()), ], 'resolve' => function ($root, $args) { return NewsRepository::add($args); } ]; mutation{ registerUser( name: "Mark", email: "mark@locaweb.com" ) { id, name, email, role, created_at } }
  45. 45. Validação
  46. 46. Todo dado que entra e sai de um serviço GraphQL é validado no SCHEMA
  47. 47. mutation{ registerUser(name: 1) { undefined_field } } { "errors": [ { "message": "Argument "name" has invalid value 1.nExpected type "String", found 1.", "locations": [ { "line": 2, "column": 22 } ] }, { "message": "Cannot query field "undefined_field" on type "User".", "locations": [ { "line": 3, "column": 5 } ] } ] }
  48. 48. Resolvers
  49. 49. São os responsáveis por resolver a QUERY, ou MUTATION, e retornar as informações
  50. 50. Todo FIELD possui um RESOLVER, mesmo que de forma implícita
  51. 51. O RESOLVER de um FIELD filho recebe o resultado do FIELD pai como argumento
  52. 52. $newsQuery = [ 'type' => Type::listOf($newsType), 'args' => [ 'id' => Type::id() ], 'resolve' => function ($root, $args) { if ($args['id'] ?? false) { return NewsRepository::findBy( ['id' => $args['id']] ); } return NewsRepository::findAll(); } ];
  53. 53. $newsType = new ObjectType([ 'name' => 'News', 'fields' => [ 'id' => Type::nonNull(Type::id()), 'user' => Type::nonNull($userType), 'media' => $mediaType, 'title' => Type::nonNull(Type::string()), 'excerpt' => [ 'type' => Type::nonNull(Type::string()), 'resolve' => function ($news, $args) { return 'Excerpt from: ' . $news->title; } ], 'text' => Type::nonNull(Type::string()), 'created_at' => Type::nonNull(Type::int()), 'status' => Type::nonNull(Type::string()), 'comments' => Type::listOf($commentType ) ] ]);
  54. 54. query { news(id:1) { id title excerpt } } { "data": { "news": [ { "id": "1", "title": "Joesley rompe com ..." , "excerpt": "Excerpt from: Joesley rompe com Tony Ramos" } ] } }
  55. 55. Adeus versionamento http://pudim.com.br/api/v1
  56. 56. Quando um FIELD for depreciado, é sinalizada a mudança no SCHEMA e definido o substituto
  57. 57. Endpoint único
  58. 58. CLIENT first
  59. 59. Entrega mais poder de fogo para o frontend
  60. 60. Cada cliente consome o serviço de acordo com a sua necessidade. PC, Mobile, Integrações...
  61. 61. Documentação
  62. 62. Documentação Introspecção
  63. 63. Todo serviço GraphQL provê a navegação por todo o SCHEMA
  64. 64. A API já nasce documentada
  65. 65. { __type(name: "News") { name fields { name } } } { "data": { "__type": { "name": "News", "fields": [ { "name": "id" }, { "name": "user" }, { "name": "media" }, { "name": "title" } //... ] } } }
  66. 66. Experiência de desenvolvimento superior
  67. 67. Adoção
  68. 68. http://graphql.org/users
  69. 69. Frontend
  70. 70. Frontend Apollo Relay Vanilla Js
  71. 71. Talk is cheap. Show me the code!
  72. 72. Dúvidas?
  73. 73. Valeu! @brunodasneves
  74. 74. Referências http://graphql.org/ https://www.youtube.com/watch?v=zVNrqo9XGOs https://github.com/chentsulin/awesome-graphql http://webonyx.github.io/graphql-php https://github.com/Youshido/GraphQL https://dev-blog.apollodata.com/

×