Diferenças na lógica da API
GitHub fornece duas APIs: uma API REST e uma API do GraphQL. Para saber mais sobre as APIs do GitHub, confira Comparando a API REST do GitHub e a API do GraphQL.
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 dificultam, e muitas vezes tornam indesejável, substituir chamadas à API REST por consultas de API do GraphQL individualmente. Incluímos abaixo exemplos específicos de migração.
Para migrar seu código da API REST para a API do GraphQL:
- Revise a especificação do GraphQL
- Examine o esquema GraphQL do GitHub
- Considere como qualquer código existente atualmente interage com a API REST do GitHub.
- Use Global Node IDs para fazer referência a objetos entre versões de API
As vantagens significativas do GraphQL incluem:
-
[Obter os dados de que você precisa e somente isso](#example-getting-the-data-you-need-and-nothing-more) -
[Campos aninhados](#example-nesting) -
[Tipagem forte](#example-strong-typing)
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 https://api.github.com/orgs/:org/members
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 à API REST recupera uma lista de solicitações de pull e as respectivas representações de resumo:
curl -v https://api.github.com/repos/:owner/:repo/pulls
Determinar se uma solicitação de pull pode ser mesclada exige a recuperação de cada solicitação de pull individualmente para obter sua representação detalhada (um volume grande de dados) e verificar se o atributo é verdadeiro ou falso:
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number
Com o GraphQL, você pode recuperar somente os atributos number e mergeable de cada solicitação de pull:
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, a recuperação de uma solicitação de pull com os commits, comentários sem revisão e revisões usando a API REST exige quatro chamadas separadas:
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/commits
curl -v https://api.github.com/repos/:owner/:repo/issues/:number/comments
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/reviews
Usando a API do GraphQL, você pode recuperar os dados com uma só 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 stituindo uma variável para o número da solicitação de pull.
Exemplo: Tipagem forte
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 em uma pull request usando a mutação do GraphOL e da especificação incorreta de um inteiro em vez de uma cadeia de caracteres para o valor de clientMutationId:
mutation {
addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "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
}
]
}
]
}
A colocação de 1234 entre aspas transforma o valor de um número 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
}
}
}
}
}