# Fazer a migração de REST para o GraphQL

Conheça as melhores práticas e considerações para migrar da GitHubAPI REST para a GitHubAPI do GraphQL.

## Diferenças na lógica da API

GitHub fornece duas APIs: uma API REST e uma API do GraphQL. Para obter mais informações sobre as APIs de GitHub, consulte [Comparando a API REST do GitHub e a API do GraphQL](/pt/enterprise-server@3.22/rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-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 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](/pt/enterprise-server@3.22/rest) para a API do GraphQL:

* Revise a [especificação do GraphQL](https://spec.graphql.org/June2018/)
* Examine o esquema [GraphQL do GitHub](/pt/enterprise-server@3.22/graphql/reference)
* Considere como qualquer código existente atualmente interage com a API REST do GitHub.
* Use [Global Node IDs](/pt/enterprise-server@3.22/graphql/guides/using-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:

```shell
curl -v http(s)://HOSTNAME/api/v3/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:

```graphql
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](/pt/enterprise-server@3.22/rest#summary-representations):

```shell
curl -v http(s)://HOSTNAME/api/v3/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:

```shell
curl -v http(s)://HOSTNAME/api/v3/repos/:owner/:repo/pulls/:number
```

Com o GraphQL, você pode recuperar somente os atributos `number` e `mergeable` de cada solicitação de pull:

```graphql
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:

```shell
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
```

Usando a **API do GraphQL**, você pode recuperar os dados com uma só consulta usando campos aninhados:

```graphql
{
  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](/pt/enterprise-server@3.22/graphql/guides/forming-calls-with-graphql#working-with-variables) 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](/pt/enterprise-server@3.22/graphql/reference) do GraphOL e da especificação incorreta de um inteiro em vez de uma cadeia de caracteres para o valor de [`clientMutationId`](/pt/enterprise-server@3.22/graphql/reference/issues#mutation-addcomment):

```graphql
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:

```json
{
  "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:

```graphql
mutation {
  addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
    clientMutationId
    commentEdge {
      node {
        body
        repository {
          id
          name
          nameWithOwner
        }
        issue {
          number
        }
      }
    }
  }
}
```