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

Design Coerente: decisões de tecnologia para APIs

Design Coerente: decisões de tecnologia para APIs

Construir uma API pode parecer simples. Transformar models em JSON, uma forma de autenticação e pronto, temos uma "API". O padrão REST é adotado como solução na maioria das vezes, mas, sem o conhecimento adequado, o design de uma API pode ficar confuso e despadronizado, dificultando a utilização dos usuários. Além disso, outras tecnologias fornecem soluções diferentes para problemas encontrados durante a concepção e/ou consumo de uma API. Essa talk analisa o REST, o RPC e o GraphQL com exemplos para que você entenda seus usuários e tome a decisão certa para sua API.

Db982994346dad910547a7c62a90dadd?s=128

Ravan Scafi

October 21, 2017
Tweet

More Decks by Ravan Scafi

Other Decks in Programming

Transcript

  1. Design Coerente: decisões de tecnologia para APIs

  2. GET /whoami Ravan Scafi Back-end Developer na Leroy Merlin Brasil

    Co-organizador do Meetup do Laravel SP Evangelista do PHPSP @ravanscafi
  3. API? O que é uma API?

  4. Interface é um elemento que proporciona uma ligação física ou

    lógica entre dois sistemas ou partes de um sistema que não poderiam ser conectados diretamente.
  5. Parte 1 Recursos vs Operações

  6. Quando Pensamos em APIs...

  7. REST REpresentational State Transfer

  8. REST Baseado em Endpoints GET /api/users/rscafi HTTP/1.1 Host: meusite.dev

  9. GET /api/users/rscafi HTTP/1.1 Host: meusite.dev REST Separado por Recursos (Substantivos)

  10. GET /api/users/rscafi HTTP/1.1 Host: meusite.dev REST Verbos HTTP indicam a

    ação
  11. REST Relação Cliente-Servidor

  12. REST Segue convenções HTTP

  13. REST Controle por Hypermedia (HATEOAS - RMM)

  14. GET /api/users/rscafi HTTP/1.1 Host: meusite.dev

  15. { "id": "rscafi", "name": "Ravan Scafi", "website": "http://ravan.me", "_links": {

    "self": { "href": "http://meusite.dev/api/users/rscafi" }, "hobbies": { "href": "http://meusite.dev/api/users/rscafi/hobbies" }, } }
  16. REST Endpoints cacheáveis

  17. REST Uniforme

  18. REST Feito para durar décadas

  19. Problemas (Spoiler: Parte 1!) REST

  20. REST - Problemas Recomendações nem sempre são seguidas

  21. REST - Problemas Excesso de Roundtrips dependendo da operação

  22. REST - Problemas Nem sempre os Verbos HTTP disponíveis falam

    com clareza
  23. Exemplo - Slack Um usuário pode ser “kickado”, “banido” ou

    pode “deixar” um canal
  24. Exemplo - Slack DELETE /users/rscafi HTTP/1.1 Host: api.slack.com

  25. Exemplo - Slack DELETE /users/rscafi HTTP/1.1 Host: api.slack.com Content-Type: application/json

    {“status”: “kicked”}
  26. Exemplo - Slack DELETE /users/rscafi HTTP/1.1 Host: api.slack.com Content-Type: application/json

    {“status”: “kicked”, “kick_channel”: “random”}
  27. Exemplo - Slack DELETE /channels/random/users/rscafi HTTP/1.1 Host: api.slack.com

  28. Exemplo - Slack DELETE /channels/random/users/rscafi HTTP/1.1 Host: api.slack.com Content-Type: application/json

    {“status”: “kicked”}
  29. REST - Problemas Operações “BULK” fogem do Padrão

  30. O que fazer? ?

  31. RPC Remote Procedure Call !

  32. RPC Baseado em Endpoints POST /api/getUser HTTP/1.1 Host: meusite.dev Content-Type:

    application/json {“id”: “rscafi”}
  33. POST /api/getUser HTTP/1.1 Host: meusite.dev Content-Type: application/json {“id”: “rscafi”} RPC

    Similar à chamada de funções
  34. “Equivalência” // definição function getUser (id) { // } //

    chamada getUser('rscafi');
  35. RPC Popularizado pelo SOAP (Simple Object Access Protocol)

  36. SOAP - Exemplo <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <soapenv:Header> <ns1:RequestHeader soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0" xmlns:ns1="https://www.google.com/apis/ads/publisher/v201605"> <ns1:networkCode>123456</ns1:networkCode> <ns1:applicationName>DfpApi-Java-2.1.0-dfp_test</ns1:applicationName> </ns1:RequestHeader> </soapenv:Header> <soapenv:Body> <getAdUnitsByStatement xmlns="https://www.google.com/apis/ads/publisher/v201605"> <filterStatement> <query>WHERE parentId IS NULL LIMIT 500</query> </filterStatement> </getAdUnitsByStatement> </soapenv:Body> </soapenv:Envelope>
  37. RPC Porém o SOAP perdeu espaço para as APIs REST

  38. REST - Exemplo GET /ads?parentId=null&limit=500 HTTP/1.1 HOST: api.example.com

  39. RPC Mas não existe somente o SOAP!

  40. RPC baseado em JSON - Exemplo POST /getAdUnitsByStatement HTTP/1.1 HOST:

    api.example.com Content-Type: application/json {"filter": "WHERE parentId IS NULL LIMIT 500"}
  41. RPC Foco em Operações

  42. Exemplo - Slack POST /api/channels.kick HTTP/1.1 Host: slack.com Content-Type: application/json

    { "token": "xxxx-xxxxxxxxx-xxxx", "channel": "random", "user": "rscafi" }
  43. RPC Relação entre (Micro) Serviços

  44. RPC A partir de uma Definição de serviços, código é

    gerado
  45. RPC Complexidade Abstraída

  46. 10.000.000.000 de chamadas RPC POR SEGUNDO! Google

  47. gRPC Framework “universal”, open source e performático

  48. gRPC HTTP/2

  49. gRPC Protocol Buffers

  50. gRPC Linguagem de Definição de Serviços

  51. gRPC service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {}

    } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
  52. gRPC Gera código para as maiores linguagens

  53. gRPC protoc --proto_path=examples/protos \ --php_out=examples/php \ --grpc_out=examples/php \ --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \

    ./examples/protos/helloworld.proto
  54. gRPC Cria stubs de Classes, onde os métodos correspondem a

    uma rota RPC
  55. gRPC $request = new Helloworld\HelloRequest(); $request->setName($name); list($reply, $status) = $client->SayHello($request)->wait();

    $message = $reply->getMessage();
  56. Problemas RPC

  57. RPC - Problemas Abstrai complexidade (!)

  58. RPC - Problemas Pode complicar mais do que se não

    estivesse presente
  59. REST vs RPC Foco Complexidade Comunicação REST Recursos Exposta Sistemas

    RPC Operações Abstraída Serviços
  60. Parte 2 Clientes

  61. Quem vai consumir esses dados?

  62. API

  63. API

  64. API

  65. Como evitar isso?

  66. BFF Backend For Frontend

  67. BFF Abordagem criada pelo SoundCloud

  68. BFF Clientes da API eram muito diferentes entre si

  69. Clientes do SoundCloud Web Mobile Parceiros

  70. BFF Cada equipe mantém uma API para atender às suas

    necessidades
  71. BFF Menos burocracia para evoluir as APIs

  72. API Monstro Web API Mobile API SoundCloud’ BFFs

  73. Problemas BFF

  74. APIs fragmentadas e em linguagens diferentes BFF - Problemas

  75. Código duplicado! BFF - Problemas

  76. Maior complexidade por cliente BFF - Problemas

  77. Mas e o REST? Então é ele o problema?

  78. API Geral Android API Web API iOS API Netflix’ API

    Gateway (existe o Zuul na frente, mas isso é tema pra outra talk)
  79. Até funciona, mas...

  80. Problemas Parte 2 REST

  81. REST - Problemas Includes vs Endpoints em recursos relacionados

  82. REST - Problemas Overfetching / Underfetching

  83. REST - Problemas HATEOAS não diz nada sobre formato de

    Requisições e Respostas
  84. REST - Problemas Não possui uma Especificação formal

  85. REST - Problemas API pode rapidamente ficar gigantesca para atender

    a todos os clientes
  86. REST - Problemas É difícil evoluir os dados sem saber

    o que os clientes de fato consomem
  87. REST - Problemas Quanto mais complexa a API fica, menos

    eficaz é o Cache
  88. GraphQL Graph Query Language

  89. GraphQL Queries + Mutations + Documentação

  90. GraphQL Única rota servindo de “tunel” para as queries

  91. GraphQL POST /graphql HTTP/1.1 Host: meusite.dev Content-Type: application/graphql { users

    { name } }
  92. GraphQL Dados da API são descritos

  93. GraphQL type User { name: String website: String hobbies: [Hobby]

    }
  94. GraphQL Um Request pede por dados específicos

  95. { user(name: "Ravan Scafi") { website, hobbies { name }

    } }
  96. GraphQL O retorno é exatamente o que foi requisitado

  97. { "user": { "website": "http://ravan.me", "hobbies": [ {"name": "PHP"}, {"name":

    "Viajar"} ] } }
  98. GraphiQL

  99. GraphQL Mutations enviam dados para o servidor

  100. GraphQL Especificação “completa” e documentada

  101. GraphQL Dados podem evoluir com (maior) facilidade

  102. Problemas (achou que tinha bala de prata?) GraphQL

  103. GraphQL - Problemas Técnicas de cache são difíceis

  104. GraphQL - Problemas Implementação pode ser complexa

  105. GraphQL - Problemas Próprias (e novas) convenções

  106. GraphQL - Problemas Upload de arquivos é “hacky”

  107. GraphQL - Problemas Sem suporte* a HyperMedia

  108. REST vs GraphQL Foco Implementação Clientes Cache REST Resiliência Evolutiva

    Parecidos Robusto GraphQL Performance Deve atender a especificação Diferentes Difícil
  109. Conclusões

  110. RPC Atende bem entre serviços e quando o foco é

    em operações.
  111. GraphQL Garante performance de Clientes e permite evolução mais rápida.

  112. REST Atende bem em CRUDs e onde as convenções HTTP

    possam ser aplicadas.
  113. REST Se bem estruturado e a banda não é um

    problema, pode ser o mais robusto dos três
  114. Dicas de Ouro

  115. Você pode usar mais de uma solução!

  116. (mas Por favor, não na mesma API)

  117. Versionamento é sempre difícil

  118. Não existe bala de prata.

  119. Entenda seus dados e seus Usuários/Clientes

  120. Empatia é a chave

  121. Empatia é a capacidade de se identificar com outra pessoa,

    de sentir o que ela sente, de querer o que ela quer, de apreender do modo como ela apreende etc.
  122. Obrigado! @ravanscafi

  123. Estamos Contratando! Devs BackEnd, Devs FrontEnd, UXs gguitte@leroymerlin.com.br

  124. Agradecimentos Agradecimentos especiais a todos do SlidesCarnival que fizeram e

    disponibilizaram o template da apresentação gratuitamente.