Diferenças na lógica da API
Fazer a migração da REST para o GraphQL representa uma mudança significativa na lógica da API. As diferenças entre a REST como um estilo e o GraphQL como uma especificação tornam difícil —e, muitas vezes indesejável—substituir as chamadas da API REST por consultas da API do GraphQL individualmente. Incluímos abaixo exemplos específicos de migração.
Para fazer a migração do seu código da API REST para a API do GraphQL:
- Revise a especificação do GraphQL
- Revise o esquema do GraphQL do GitHub
- Considere como qualquer código existente que você tem atualmente interage com a API REST do GitHub
- Use IDs dos nó global para fazer referência a objetos entre as versões da API
As vantagens significativas do GraphQL incluem:
Aqui estão exemplos de cada um.
Exemplo: Obter os dados de que você precisa e somente isso
Uma única chamada da REST API recupera uma lista dos membros da sua organização:
curl -v http(s)://[hostname]/api/v3/orgs/:org/membros
A carga da REST contém dados excessivos se seu objetivo é recuperar apenas nomes de integrantes e links para avatares. No entanto, uma consulta do GraphQL retorna apenas o que você especifica:
query {
organization(login:"github") {
membersWithRole(first: 100) {
edges {
node {
name
avatarUrl
}
}
}
}
}
Considere outro exemplo: recuperar uma lista de pull requests e verificar se cada um é mesclável. Uma chamada para a API REST recupera uma lista de pull requests e suas representações resumidas:
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls
Determinar se um pull request pode ser mesclado demanda recuperar cada pull request individualmente para sua representação detalhada (uma grande carga), bem como verificar seu atributo mesclável
é verdadeiro ou falso:
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number
Com o GraphQL, você pode recuperar apenas os atributos número
e mesclável
para cada pull request:
query {
repository(owner:"octocat", name:"Hello-World") {
pullRequests(last: 10) {
edges {
node {
number
mergeable
}
}
}
}
}
Exemplo: Aninhamento
Fazer consulta com campos aninhados permite substituir várias chamadas de REST por menos consultas do GraphQL. Por exemplo, recuperar um pull request junto com seus commits, comentários que não são de revisão e revisões usando a API REST exige quatro chamadas separadas:
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number/commits
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/issues/:number/comments
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number/reviews
Ao usar a API do GraphQL, você pode recuperar os dados com uma única consulta usando campos aninhados:
{
repository(owner: "octocat", name: "Hello-World") {
pullRequest(number: 1) {
commits(first: 10) {
edges {
node {
commit {
oid
message
}
}
}
}
comments(first: 10) {
edges {
node {
body
author {
login
}
}
}
}
reviews(first: 10) {
edges {
node {
state
}
}
}
}
}
}
Você também pode estender o poder dessa consulta se substitui uma variável para o número do pull request.
Exemplo: Digitação não flexível
Os esquemas do GraphQL são digitados de modo rígido, o que torna o gerenciamento dos dados mais seguro.
Considere um exemplo de adição de um comentário a um problema ou pull request usando uma mutação do GraphQL e especificando por engano um número inteiro em vez de uma string para o valor de clientMutationId
:
mutation {
addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) "Looks good to me!"}) {
clientMutationId
commentEdge {
node {
body
repository {
id
name
nameWithOwner
}
issue {
number
}
}
}
}
}
Executar esta consulta retorna erros especificando os tipos esperados para a operação:
{
"data": null,
"errors": [
{
"message": "Argument 'input' on Field 'addComment' has an invalid value. Expected type 'AddCommentInput!'.",
"locations": [
{
"line": 3,
"column": 3
}
]
},
{
"message": "Argument 'clientMutationId' on InputObject 'AddCommentInput' has an invalid value. Expected type 'String'.",
"locations": [
{
"line": 3,
"column": 20
}
]
}
]
}
Colocar 1234
entre aspas transforma o valor de um inteiro em uma string, o tipo esperado:
mutation {
addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
clientMutationId
commentEdge {
node {
body
repository {
id
name
nameWithOwner
}
issue {
number
}
}
}
}
}