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 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
- 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 de nó globais para referenciar objetos entre 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 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 a representação detalhada (um conteúdo grande) e a verificação do atributo mergeable
ser 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 substituindo uma variável pelo número da solicitação de pull.
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 uma solicitação de pull ou um problema usando uma mutação do GraphQL 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 inteiro em uma cadeia de caracteres, 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
}
}
}
}
}