44
GraphQL o que, como e quando QCon SP 2018

GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

  • Upload
    others

  • View
    25

  • Download
    0

Embed Size (px)

Citation preview

Page 1: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQLo que, como e quando

QCon SP 2018

Gustavo Sverzut Barbieri
Gustavo Sverzut Barbieri
Page 2: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Introdução pessoalProblemas de APIs REST

Soluções GraphQLCaso: GitHub

Caso: Cartão Elo

Agenda

Page 3: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Gustavo Sverzut Barbieri

- Desenvolvedor desde os 9 anos

- Web desde 1998 (Perl, CGI…)

- UNICAMP 2001-2005

- Serviços de desenvolvimento de sw

- Apaixonado por eficiência

- Sistemas embarcados e IoT

- Sistemas Complexos

- P&D

Engenheiro de ComputaçãoProFUSION

Page 4: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Problemas RESTPor que criar o GraphQL?

Page 5: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: Representational State Transfer

- Modelo de Arquitetura

- Vários pontos de acesso (URL), um por recurso

- Cada operação (GET, POST, PUT…) retorna um conjunto de dados fixo

- Adicionar ou remover dados ou parâmetros quebra a API (nova versão)

Page 6: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: ilustrado

Dado portador CPF 12345678900, pegue os 4 últimos dígitos (last4) e o BIN do primeiro token do primeiro cartão.

GET /v1/card-holder/12345678900{…, "name": "José da Silva", "cards": [ "xyz", "xpto", …],…}

GET /v1/card/xyz{…, "last4": "1234", "bin": "5035", "cardHolder": "1234", "tokens": ["abc", "def", …],…}

GET /v1/card-token/abc{…, "last4": "1234", "bin": "6046", "card": "xyz", "cardHolder": "1234",…}

CardHolder Card Card

Token

Page 7: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GET /v1/card-holder/12345678900{…, "name": "José da Silva", "cards": [ "xyz", "xpto", …],…}

GET /v1/card/xyz{…, "last4": "1234", "bin": "5035", "cardHolder": "1234", "tokens": ["abc", "def", …],…}

GET /v1/card-token/abc{…, "last4": "1234", "bin": "6046", "card": "xyz", "cardHolder": "1234",…}

REST: ilustrado

estadotransferido(Portador)

estadotransferido(Cartão)

estadotransferido(Token)

Dado portador CPF 12345678900, pegue os 4 últimos dígitos (last4) e o BIN do primeiro token do primeiro cartão.

CardHolder Card Card

Token

Page 8: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: ilustradoGET /v1/card-holder/12345678900{…, "name": "José da Silva", "cards": [ "xyz", "xpto", …],…}

GET /v1/card/xyz{…, "last4": "1234", "bin": "5035", "cardHolder": "1234", "tokens": ["abc", "def", …],…}

GET /v1/card-token/abc{…, "last4": "1234", "bin": "6046", "card": "xyz", "cardHolder": "1234",…}

dados inúteis!

Dado portador CPF 12345678900, pegue os 4 últimos dígitos (last4) e o BIN do primeiro token do primeiro cartão.

CardHolder Card Card

Token

Page 9: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: problemas

- API bem normalizada resulta em muitas conexões HTTP;- Tráfego de dados inúteis ao aplicativo;- Endpoints otimizados para aplicativos

- Mudanças de requisitos no front-end costumam precisar de adaptações no backend;

- Falta Documentação;- Falta Validação e Garantias;- Falta ambiente de testes/playground.

Page 10: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: resolvendo problemas de ambiente

- Documentação via Swagger- Validação com JSON Schema- Testes com Postman ou cURL

Page 11: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: resolvendo problemas de execução

Extensões:- Parâmetros para controlar campos a

retornar;- Parâmetros para controlar paginação,

ordenação...;- Desnormalização para reduzir número de

consultas;… mas são específicas de fornecedores!

GET /v2/card/xyz?fields=last4,bin,tokens{…, "last4": "1234", "bin": "5035", "cardHolder": "1234", "tokens": ["abc", "def", …],…}

GET /v2/card/xyz?fields=last4,bin,tokens.limit(1)

{ "last4": "1234", "bin": "5035", "tokens": ["abc", "def", …],}

GET /v2/card-holder/1234?fields=name,cards.limit(1){last4,bin}

{ "name": "José da Silva", "cards": [{"last4": "1234, "bin": "5035"}],}

Facebook Graph API

Page 12: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

REST: problemas com extensões

GET /v2/card-holder/1234?fields=name,cards.limit(1){last4,bin}

- Linguagem de domínio específica (DSL)- Validação- Documentação

Page 13: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQLResolvendo problemas REST

Page 14: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

cursor

GraphQL

- Linguagem de Consulta de Grafos- Nós: dados

- Arestas: relacionamentos

- Não é:- Protocolo de Rede

- Descrição de Banco de Dados

- Descrição de Classes em OOP

- Origem: Facebook após tratar diversos problemas com REST

Card

Token

CardHolder

Addr.

City

Zip

Name

ID

ID

cursor

Page 15: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL

- Declaração de tipos e consultas via Schema

- Tipagem forte

- Sempre verificado

- Documentação embutida no schema, com consulta/introspecção

- Interfaces

# Portador de cartão… type CardHolder implements Node { # Identificador Global Único … id: ID!

# Nome completo do portador … name: String

# Cartões em posse… cards( # Limita a lista às primeiras entradas… first: Int, # Inicia após o cursor opaco… after: String, # … outros argumentos … ): CardsConnection}

type Query { node(id: ID!): Node cardHolders(☰): CardHoldersConnection}

Page 16: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL# Portador de cartão… type CardHolder implements Node { # Identificador Global Único … id: ID!

# Nome completo do portador … name: String

# Cartões em posse… cards( # Limita a lista às primeiras entradas… first: Int, # Inicia após o cursor opaco… after: String, # … outros argumentos … ): CardsConnection}

type Query { node(id: ID!): Node cardHolders(☰): CardHoldersConnection}

comentários são armazenados como descrição,convenção por formatação Markdown

declaração de Objetos e interfaces: validação e documentação!

Todos os campos também são consultas, com tipos de retorno

Todas consultas podem ter argumentos,documentados e com tipos

Page 17: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL

- Consultas aninhadas- Linguagem de consultas bem definida

- Argumentos

- Variáveis

- Resultados espelham estrutura da consulta

- Fragmentos de consulta

{"data": { "node": {

"name": "João da Silva", "cards": { "edges": [ "node": { "last4": "1234", "bin": "5035" } ] } }}

query Nome($holderId: ID!) { node(id: $holderId) { ... on CardHolder { name cards(first: 1) { edges { node { last4 bin } } } } }}

Page 18: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

query Nome($holderId: ID!) { node(id: $holderId) { ... on CardHolder { name cards(first: 1) { edges { node { last4 bin } } } } }}

GraphQL

{"data": { "node": {

"name": "João da Silva", "cards": { "edges": [ "node": { "last4": "1234", "bin": "5035" } ] } }}

operação: queryvariáveis

Page 19: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL

query Nome($holderId: ID!) { node(id: $holderId) { ... on CardHolder { name cards(first: 1) { edges { node { last4 bin } } } } }}

{"data": { "node": {

"name": "João da Silva", "cards": { "edges": [ "node": { "last4": "1234", "bin": "5035" } ] } }}

consulta raiz

argumentos

consultas aninhadas

resultado espelhado

Page 20: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

query Nome($holderId: ID!) { node(id: $holderId) { ... on CardHolder { name cards(first: 1) { edges { node { last4 bin } } } } }}

GraphQL

{"data": { "node": {

"name": "João da Silva", "cards": { "edges": [ "node": { "last4": "1234", "bin": "5035" } ] } }}

fragmentos: seleção de tipo

("Cast")

Page 21: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: múltiplas consultas raiz

- Consultas executadas em paralelo

- Apelidos para diferenciar consultas com argumentos diferentes

query { n0: node(id: "id0") { ... on CardInterface { last4 holder { name } } } n1: node(id: "id0") { ... on CardInterface { last4 holder { name } } } bin(number: "509069") { issuer { name } }}

{"data": { "n0": {

"last4": "1234", "holder": { "João ..." } } }, "n1": {

"last4": "2468", "holder": { "José ..." } } }, "bin": { "issuer": { "name": "Banco ...", } }}

Page 22: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: múltiplas consultas raiz

query { n0: node(id: "id0") { ... on CardInterface { last4 holder { name } } } n1: node(id: "id1") { ... on CardInterface { last4 holder { name } } } bin(number: "509069") { issuer { name } }}

apelidos renomeiam retorno

em paraleloexecução

em paralelo

em paralelo

{"data": { "n0": {

"last4": "1234", "holder": { "João ..." } } }, "n1": {

"last4": "2468", "holder": { "José ..." } } }, "bin": { "issuer": { "name": "Banco ...", } }}

Page 23: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: mutações

- Mutações alteram e retornam o estado

- Executadas em série- Consulta de retorno em paralelo

mutation { a0: associatePSPMerchant(☰) { pspId legalId } a1: associatePSPMerchant(☰) { pspId legalId }}

{"data": { "a0": { "pspId": "1234", "legalId": "1234...", }, "a1": { "pspId": "222", "legalId": "2345...", }}

Page 24: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: mutações

mutation { a0: associatePSPMerchant(☰) { pspId legalId } a1: associatePSPMerchant(☰) { pspId legalId }}

{"data": { "a0": { "pspId": "1234", "legalId": "1234...", }, "a1": { "pspId": "222", "legalId": "2345...", }}

em paralelo

em paralelo

executado primeiro

executado depois

Page 25: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: erros

- Consultas retornam: null- Até o primeiro elemento

null-able- Motor sempre garante retorno

correto- Listagem de erros

query { a: bin(number: "invalid") { issuer { name } } b: bin(number: "509069") { issuer { name # server bug! } } c: bin(number: "509069") { issuer { url # server bug! } }}

{"data": { "a": null,

"b": null,

"b": { "issuer": { "url": null } } }, "errors": [ {"message": "Bin inválido", "path": ["a"] }, {"message": "Campo null!", "path": ["b", "issuer", "name"] } {"message": "Server Bug", "path": ["c", "issuer", "url"] } ] }

- bin() pode retornar null- BIN { issuer } é não-nulo- CardIssuer { name } é não-nulo- CardIssuer { url} é null-able

Page 26: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Relay

- Relay: adiciona GraphQL a clientes React.JS;- Foco em desempenho e facilidade de uso;- Uso extensivo de fragmentos;- Convenções adicionais:

- Identificação de Objetos: cache e atualização

- Conexões: paginação

- Mutações: previsibilidade e idempotência

https://facebook.github.io/relay/docs/en/graphql-server-specification.html

adotados por todos os frameworks,cliente e servidor: Apollo, Graphene...

Page 27: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Relay: Identificação de Objetos

- Interface declara objeto com identificação global;- Permite cache global do aplicativo;- Fragmentos obtém dados, populando cache;- Relay mantém o cache e informa utilizadores sobre atualizações

interface Node { id: ID!}

type Query { node(id: ID!): Node}

cache

React Components

Page 28: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Relay: Conexões

- Conexões de Nós do Grafo;- Arestas podem conter mais informações, ex: data da associação, custo…- Parâmetros de paginação;- Informações de paginação;- Cursores opacos.

type CardsConnection { edges: [CardsEdge] pageInfo: PageInfo! # outros campos que achar conveniente totalCount: Int}type CardsEdge { node: Card cursor: String! # opaco # outros campos que achar conveniente}type PageInfo { hasPreviousPage: Boolean! hasNextPage: Boolean! startCursor: String endCursor: String}

type Query { cards( first: Int # limita elementos no retorno after: String # cursor de início last: Int # limita elementos no retorno before: String # cursor de término filter: CardFilterInput # filtros ): CardsConnection}

Page 29: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Relay: Mutações- Assinatura com nomenclatura padrão;- clientMutationId para reconciliação e idempotência;

type ActivateCardTokenInput { clientMutationId: String # opaco # outros campos que achar conveniente cardTokenId: String sensitive: String}type ActivateCardTokenPayload { clientMutationId: String # opaco # outros campos que achar conveniente cardToken: CardToken # null se não existe}type Mutation { activateCardToken( input: ActivateCardTokenInput ): ActivateCardTokenPayload}

activateCardToken(input:{clientMutationId: "x", ☰})

activateCardToken(input:{clientMutationId: "x", ☰})

executa

cliente servidor

detectaréplica

tenta novamente

Page 30: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: Benefícios

- Schema- Linguagem de Domínio Específico (DSL) fácil e bem documentada- Tipagem forte e garantida pelo motor- Consultas de introspeção built-in (__schema, __type)- Documentação faz parte do Schema- Múltiplas consultas ou mutações por requisição

Page 31: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: Playground - GraphiQL

https://github.com/graphql/graphiql

Page 32: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GraphQL: não...

GraphQL não especifica:- Transporte, em geral HTTP;- Segurança, em geral TLS (HTTPS);- Serialização de dados, em geral JSON;- Autenticação e Autorização, em geral OAuth v2 via HTTP + Headers.

Page 33: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GitHubCaso de Sucesso

API v4, Setembro de 2016

- Escalabilidade

- Flexibilidade

- Paginação

- Tipagem

- Documentação

Page 34: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GitHub: motivos da mudança

- API REST responsável por 60% dos acessos ao DB- Resultados continham muitos dados inúteis, "*_url" para navegação…- Integradores reclamavam de falta de dados úteis- 2-3 requisições para visualização completa de um recurso- Complicado manter documentação correta, com tipos e garantias

Page 35: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GitHub: a mudança - Primeiro objetivo: reações Emoji nos comentários- Foi necessário modelar uma grande parte do sistema:

- Usuário

- Repositório

- Issues / Pull Requests

- Comentários

- Ajuda: aliados no time de frontend (uso de React & Relay)- Em produção concomitantemente com REST- Bons resultados = v4!

User

Repository

IssuesPR

Comments

Reactions

Page 36: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GitHub: o que disseram no anúncio

GraphQL represents a massive leap forward for API development.

Type safety, introspection, generated documentation, and predictable responses

benefit both the maintainers and consumers of our platform. We’re looking forward to our new era of a GraphQL-backed platform, and we hope that you do, too!

https://githubengineering.com/the-github-graphql-api/

Schema!

Page 37: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

GitHub: justificativa da mudança

GitHub chose GraphQL for our API v4 because it offers significantly more flexibility for our integrators. The ability to define precisely the data you want—and only the data you want—is a powerful advantage over the REST API v3 endpoints. GraphQL lets you replace multiple REST requests with a single call to fetch the data you specify.

https://developer.github.com/v4/#why-is-github-using-graphql

Eficiência & Flexibilidade

Page 38: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Cartão EloCaso de Sucesso - Brasil

Outubro de 2017

- GraphQL desde o início

- Várias unidades de negócios

- Uniformidade

- Experiência do Desenvolvedor

https://dev.elo.com.br/

Page 39: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Experiência do Desenvolvedor

Design APIPortal Dev

FuncionamentoAPI Gateway

Backend

Page 40: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Cartão Elo

Experiência de Usuário:

- Suporte Nacional- Segurança- Documentação- Facilidade de Uso- Extensível

- Moto: API First

- Consumo interno e externo

- Diversas Áreas de Negócios:- Cadastro de Portadores- Seguros- Tabela de Bins- Precificação- Tokenização- Histórico de Transações- ...

GraphQL!

Page 41: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Cartão Elo

https://dev.elo.com.br/documentacao/tabela-de-bins#tabela-de-bins/Consultas

Playground similar ao GraphiQL

Documentação gerada via Schema

Page 42: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Cartão Elo

BINCard Holder

Card Card Token

CardIssuer

Card Brand

Card Network

Card Usage

Merchant

Address

Page 43: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

o que? dados como grafo

como? navegando informação

quando? eficiência e facilidade

Page 44: GraphQL - QConSPGraphQL represents a massive leap forward for API development. Type safety, introspection, generated documentation, and predictable responses benefit both the maintainers

Gustavo Sverzut Barbieri<[email protected]>

Obrigado!

Perguntas?