# Realizar chamadas com o GraphQL

Aprenda a efetuar a autenticação da a API do GraphQL e, em seguida, aprenda a criar e executar consultas e mutações.

## Autenticar com o GraphQL

Você pode se autenticar na API do GraphQL usando um personal access token, GitHub Appou OAuth app.

### Autenticando com um personal access token

Para autenticar com um personal access token, siga as etapas em [Gerenciar seus tokens de acesso pessoal](/pt/enterprise-server@3.22/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). Os dados que você está solicitando determinarão as permissões ou os escopos necessários.

Por exemplo, selecione a permissão "issues:read" para ler todas as issues nos repositórios a que seu token tem acesso.

Todos os itens fine-grained personal access token incluem acesso de leitura a repositórios públicos. Para acessar repositórios públicos com um personal access token (classic), selecione o escopo "public\_repo".

Se o token não tiver os escopos ou permissões necessários para access um recurso, a API retornará uma mensagem de erro que declara os escopos ou permissões de que seu token precisa.

### Autenticando com um GitHub App

Se você quiser usar a API em nome de uma organização ou de outro usuário, GitHub recomenda que você use uma GitHub App. Para atribuir a atividade ao seu aplicativo, você pode fazer com que o aplicativo se autentique como uma instalação de aplicativo. Para atribuir a atividade do aplicativo a um usuário, você pode fazer com que o aplicativo se autentique em nome de um usuário. Em ambos os casos, você vai gerar um token que pode ser usado para se autenticar na API do GraphQL. Para obter mais informações, consulte [Registrando um aplicativo GitHub](/pt/enterprise-server@3.22/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) e [Sobre a autenticação com um aplicativo GitHub](/pt/enterprise-server@3.22/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app).

### Autenticando com um OAuth app

Para autenticar com um token OAuth de um OAuth app, você deve primeiro autorizar seu OAuth app usando um fluxo de aplicativo web ou um fluxo de dispositivo. Em seguida, você pode usar o token de acesso que recebeu para acessar a API. Para obter mais informações, consulte [Criar um aplicativo OAuth](/pt/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) e [Autorizar aplicativos OAuth](/pt/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps).

## O ponto final do GraphQL

A API REST tem vários pontos de extremidade. Com a API do GraphQL, o ponto de extremidade permanece constante, seja qual for a operação executada. ParaGitHub Enterprise Server, esse ponto de extremidade é:

<pre>http(s)://HOSTNAME/api/graphql</pre>

## Comunicação com o GraphQL

Como as operações do GraphQL consistem em JSON multilinha, GitHub recomenda usar os clientes [GraphQL](/pt/enterprise-server@3.22/graphql/guides/using-graphql-clients) para fazer chamadas graphQL. Você também pode usar `curl` ou qualquer outra biblioteca que fale HTTP.

Na REST, os [verbos HTTP](/pt/enterprise-server@3.22/rest#http-verbs) determinam a operação executada. No GraphQL, você fornecerá um texto codificado por JSON se estiver realizando uma consulta ou uma mutação. Portanto, o verbo HTTP é `POST`. A exceção a isso é uma [consulta de introspecção](/pt/enterprise-server@3.22/graphql/guides/introduction-to-graphql#discovering-the-graphql-api), que é um `GET` simples para o ponto de extremidade. Para obter mais informações sobre GraphQL versus REST, consulte [Fazer a migração de REST para o GraphQL](/pt/enterprise-server@3.22/graphql/guides/migrating-from-rest-to-graphql).

Para consultar o GraphQL em um comando `curl`, faça uma solicitação `POST` com uma carga JSON. O conteúdo precisa conter uma cadeia de caracteres chamada `query`:

```shell
curl -H "Authorization: bearer TOKEN" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" http(s)://HOSTNAME/api/graphql
```

> \[!NOTE]
> O valor da cadeia de caracteres `"query"` deve fazer o escape de caracteres de nova linha ou o esquema não o analisará corretamente. Para o corpo de `POST`, use aspas duplas externas e aspas duplas internas com escape.

### Sobre consultas e operações de mutação

Os dois tipos de operações permitidas na API do GraphQL do GitHub são *queries* e *mutations*. Comparando o GraphQL com a REST, as consultas operam como solicitações `GET`, enquanto as mutações operam como `POST`/`PATCH`/`DELETE`. O nome da mutação determina qual modificação é executada.

Para obter informações sobre a limitação de taxa, confira [Limites de taxas e limites de consultas para a API GraphQL](/pt/enterprise-server@3.22/graphql/overview/rate-limits-and-query-limits-for-the-graphql-api).

As consultas e mutações compartilham formas semelhantes, com algumas diferenças importantes.

### Sobre consultas

As consultas do GraphQL retornam apenas os dados especificados. Para formar uma consulta, você deve especificar [campos dentro de campos](/pt/enterprise-server@3.22/graphql/guides/introduction-to-graphql#field) (também conhecidos como *subcampos aninhados*) até retornar apenas valores escalares.

As consultas são estruturadas da seguinte forma:

<pre>query {
  JSON-OBJECT-TO-RETURN
}</pre>

Para ver um exemplo do mundo real, confira [Exemplo de consulta](#example-query).

### Sobre as mutações

Para formar uma mutação, você deve especificar três coisas:

1. *Nome da mutação*. O tipo de modificação que você deseja realizar.
2. *Objeto de entrada*. Os dados que você deseja enviar para o servidor, compostos de *campos de entrada*. Passe-o como um argumento para o nome de mutação.
3. *Objeto de carga*. Os dados que você deseja retornar do servidor, compostos de *campos de retorno*. Passe-o como o texto do nome da mutação.

As mutações são estruturadas da seguinte forma:

<pre>mutation {
  MUTATION-NAME(input: {MUTATION-NAME-INPUT!}) {
    MUTATION-NAME-PAYLOAD
  }
}</pre>

O objeto de entrada deste exemplo é `MutationNameInput`, e o objeto de conteúdo é `MutationNamePayload`.

Na referência de mutações, os *campos de entrada* listados são os que você passa como objeto de entrada. Os *campos de retorno* listados são o que você transmite como o objeto de conteúdo.

Para ver um exemplo do mundo real, confira [Exemplo de mutação](#example-mutation).

## Trabalhar com variáveis

As [variáveis](https://graphql.org/learn/queries/#variables) podem tornar as consultas mais dinâmicas e eficientes, além de reduzir a complexidade quando transmitir os objetos de entrada de mutação.

Aqui está um exemplo de consulta com uma única variável:

```graphql
query($number_of_repos:Int!) {
  viewer {
    name
     repositories(last: $number_of_repos) {
       nodes {
         name
       }
     }
   }
}
variables {
   "number_of_repos": 3
}
```

Existem três etapas para usar variáveis:

1. Defina a variável fora da operação em um objeto `variables`:

   ```graphql
   variables {
      "number_of_repos": 3
   }
   ```

   O objeto deve ser um JSON válido. Esse exemplo mostra um tipo de variável `Int` simples, mas é possível definir tipos de variáveis mais complexos, como objetos de entrada. Você também pode definir diversas variáveis aqui.

2. Passe a variável para a operação como argumento:

   ```graphql
   query($number_of_repos:Int!){
   ```

   O argumento é um par chave-valor, em que a chave é o *nome* que começa com `$` (por exemplo, `$number_of_repos`), e o valor é o *tipo* (por exemplo, `Int`). Adicione um `!` para indicar se o tipo é obrigatório. Se você definiu diversas variáveis, inclua-as aqui como múltiplos argumentos.

3. Use a variável dentro da operação:

   ```graphql
   repositories(last: $number_of_repos) {
   ```

   Neste exemplo, substituímos a variável pelo número de repositórios a ser recuperados. Especificamos um tipo na etapa 2, porque o GraphQL impõe uma digitação forte.

Este processo torna o argumento da consulta dinâmico. Agora, podemos simplesmente alterar o valor no objeto `variables` e manter o restante da consulta inalterado.

O uso de variáveis como argumentos permite que você atualize os valores dinamicamente no objeto `variables` sem alterar a consulta.

## Consulta de exemplo

Vamos analisar uma questão mais complexa e colocar essas informações no contexto.

A consulta a seguir pesquisa o repositório `octocat/Hello-World`, encontra as 20 issues fechadas mais recentes e retorna o título, a URL e os 5 rótulos de cada issue:

```graphql
query {
  repository(owner:"octocat", name:"Hello-World") {
    issues(last:20, states:CLOSED) {
      edges {
        node {
          title
          url
          labels(first:5) {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    }
  }
}
```

Observando a composição linha por linha:

* `query {`

  Como queremos ler os dados do servidor e não modificá-los, `query` é a operação raiz. (Se você não especificar uma operação, `query` também será o padrão).

* `repository(owner:"octocat", name:"Hello-World") {`

  Para iniciar a consulta, queremos encontrar um objeto [`repository`](/pt/enterprise-server@3.22/graphql/reference/repos#object-repository). A validação de esquema indica que esse objeto exige um `owner` e um argumento `name`.

* `issues(last:20, states:CLOSED) {`

  Para considerar todas as questões no repositório, chamamos o objeto `issues`. (*Podemos* consultar um só `issue` em um `repository`, mas, para isso, precisaremos saber o número do problema que queremos retornar e fornecê-lo como um argumento).

  Alguns detalhes sobre o objeto `issues`:

  * A [documentação](/pt/enterprise-server@3.22/graphql/reference/repos#object-repository) nos informa que esse objeto tem o tipo `IssueConnection`.
  * A validação de esquema indica que esse objeto exige um número de resultados `last` ou `first` como argumento, ou seja, fornecemos `20`.
  * A [documentação](/pt/enterprise-server@3.22/graphql/reference/repos#object-repository) também informa que esse objeto aceita um argumento `states`, que é uma enumeração [`IssueState`](/pt/enterprise-server@3.22/graphql/reference/issues#enum-issuestate) que aceita valores `OPEN` ou `CLOSED`. Para localizar apenas os problemas fechados, damos à chave `states` um valor igual a `CLOSED`.

* `edges {`

  Sabemos que `issues` é uma conexão porque ela tem o tipo `IssueConnection`. Para recuperar dados sobre questões individuais, precisamos acessar o nó por meio de `edges`.

* `node {`

  Aqui, recuperamos o nó no fim da borda. A [`IssueConnection` documentação](/pt/enterprise-server@3.22/graphql/reference/issues#object-issueconnection) indica que o nó no final do tipo é um objeto `IssueConnection` type is an `Issue`.

* Agora que sabemos que estamos recuperando um objeto `Issue`, podemos dar uma olhada na [documentação](/pt/enterprise-server@3.22/graphql/reference/issues#object-issue) e especificar os campos que queremos retornar:

  ```graphql
  title
  url
  labels(first:5) {
    edges {
      node {
        name
      }
    }
  }
  ```

  Aqui, especificamos os campos `title`, `url` e `labels` do objeto `Issue`.

  O campo `labels` tem o tipo [`LabelConnection`](/pt/enterprise-server@3.22/graphql/reference/issues#object-labelconnection). Assim como acontece com o objeto `issues`, como `labels` é uma conexão, precisamos percorrer as bordas até um nó conectado: o objeto `label`. No nó, podemos especificar os campos de objeto `label` que queremos retornar, nesse caso, `name`.

Você pode notar que a execução dessa consulta no repositório público `Hello-World` do Octocat não retornará muitos rótulos. Tente executá-la em um dos seus próprios repositórios que usam etiquetas, e provavelmente você verá uma diferença.

## Exemplo de mutação

De modo geral, as mutações exigem informações que você só pode encontrar ao realizar primeiro uma consulta. Este exemplo mostra duas operações:

1. Uma consulta para obter um ID de problema.
2. Uma mutação para adicionar uma reação de emojis ao problema.

```graphql
query FindIssueID {
  repository(owner:"octocat", name:"Hello-World") {
    issue(number:349) {
      id
    }
  }
}

mutation AddReactionToIssue {
  addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
```

Vamos analisar o exemplo. A tarefa parece simples: adicione uma reação emoji a um problema.

Então, como sabemos iniciar com uma consulta? Ainda não sabemos.

Uma vez que desejamos modificar os dados no servidor (anexar um emoji a um problema), começamos procurando uma mutação útil no esquema. A documentação de referência mostra a mutação [`addReaction`](/pt/enterprise-server@3.22/graphql/reference/reactions#mutation-addreaction), com esta descrição: `Adds a reaction to a subject.` Perfeito!

A documentação sobre a mutação menciona três campos de entrada:

* `clientMutationId` (`String`)
* `subjectId` (`ID!`)
* `content` (`ReactionContent!`)

Os `!`s indicam que `subjectId` e `content` são campos obrigatórios. Um `content` obrigatório faz sentido: desejamos adicionar uma reação e, portanto, precisamos especificar o emoji que deve ser usado.

Mas por que `subjectId` é obrigatório? Isso ocorre porque a `subjectId` é a única maneira de identificar a *qual* problema de *qual* repositório é preciso reagir.

É por isso que começamos este exemplo com uma consulta: para obter a `ID`.

Vamos examinar a consulta linha por linha:

* `query FindIssueID {`

  Aqui, estamos executando uma consulta e a nomeamos `FindIssueID`. Observe que nomear uma consulta é opcional; nós damos um nome aqui para que possamos incluí-la na mesma janela do cliente da GUI que a mutação.

* `repository(owner:"octocat", name:"Hello-World") {`

  Especificamos o repositório consultando o objeto `repository` e transmitindo os argumentos `owner` e `name`.

* `issue(number:349) {`

  Especificamos o problema ao qual é preciso reagir consultando o objeto `issue` e transmitindo um argumento `number`.

* `id`

  É aqui que recuperamos o `id` de `https://github.com/octocat/Hello-World/issues/349` para passar como o `subjectId`.

Quando executamos a consulta, obtemos a `id`: `MDU6SXNzdWUyMzEzOTE1NTE=`

> \[!NOTE]
> O `id` retornado na consulta é o valor que passaremos como o `subjectID` na mutação. Nem a documentação nem a introspecção do esquema indicará essa relação; você precisará entender os conceitos por trás dos nomes para descobrir isso.

Com a identificação conhecida, podemos prosseguir com a mutação:

* `mutation AddReactionToIssue {`

  Aqui, estamos executando uma mutação e a nomeamos `AddReactionToIssue`. Assim como acontece com as consultas, nomear uma mutação é opcional; damos um nome aqui para que possamos incluí-lo na mesma janela de cliente gui que a consulta.

* `addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {`

  Vamos examinar essa linha:

  * `addReaction` é o nome da mutação.
  * `input` é a chave de argumento obrigatória. Isso sempre será `input` para uma mutação.
  * `{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}` é o valor de argumento obrigatório. Este será sempre um objeto de entrada (daí as chaves) composto por campos de entrada (`subjectId` e `content` neste caso) para uma mutação.

  Como sabemos qual é o valor a usar para o conteúdo? A [`addReaction` documentação](/pt/enterprise-server@3.22/graphql/reference/reactions#mutation-addreaction) nos diz que o campo `content` tem o tipo [`ReactionContent`](/pt/enterprise-server@3.22/graphql/reference/reactions#enum-reactioncontent), que é um enum, porque apenas determinadas reações de emoji são aceitas nas issues do GitHub. Estes são os valores permitidos para reações (observe que alguns valores diferem de seus nomes de emojis correspondentes):

  <table style="width:20%">
  <thead>
  <tr>
  <th scope="col" style="text-align:left">Conteúdo</th>
  <th scope="col" style="text-align:left">Emoji</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td style="text-align:left"><code>+1</code></td>
  <td style="text-align:left">👍</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>-1</code></td>
  <td style="text-align:left">👎</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>laugh</code></td>
  <td style="text-align:left">😄</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>confused</code></td>
  <td style="text-align:left">😕</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>heart</code></td>
  <td style="text-align:left">❤️</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>hooray</code></td>
  <td style="text-align:left">🎉</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>rocket</code></td>
  <td style="text-align:left">🚀</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>eyes</code></td>
  <td style="text-align:left">👀</td>
  </tr>
  </tbody>
  </table>

* O resto da chamada é composto pelo objeto da carga. Aqui é onde especificamos os dados que desejamos que o servidor retorne depois de termos efetuado a mutação. Essas linhas são provenientes da [`addReaction` docs](/pt/enterprise-server@3.22/graphql/reference/reactions#mutation-addreaction), que contêm três campos de retorno possíveis.

  * `clientMutationId` (`String`)
  * `reaction` (`Reaction!`)
  * `subject` (`Reactable!`)

  Neste exemplo, retornamos os dois campos obrigatórios (`reaction` e `subject`), ambos com subcampos obrigatórios (`content` e `id`, respectivamente).

Ao executarmos a mutação, esta é a resposta:

```json
{
  "data": {
    "addReaction": {
      "reaction": {
        "content": "HOORAY"
      },
      "subject": {
        "id": "MDU6SXNzdWUyMTc5NTQ0OTc="
      }
    }
  }
}
```

É isso! Confira sua [reção ao problema](https://github.com/octocat/Hello-World/issues/349) passando o mouse sobre o :tada: para localizar seu nome de usuário.

Observação final: quando você passa vários campos em um objeto de entrada, a sintaxe pode ficar pesada. Pode ser útil mover os campos para uma [variável](#working-with-variables). Veja como você poderia reescrever a mutação original usando uma variável:

```graphql
mutation($myVar:AddReactionInput!) {
  addReaction(input:$myVar) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
variables {
  "myVar": {
    "subjectId":"MDU6SXNzdWUyMTc5NTQ0OTc=",
    "content":"HOORAY"
  }
}
```

> \[!NOTE]
> Você poderá observar que o valor do campo `content` no exemplo anterior (em que ele é usado diretamente na mutação) não tem aspas em torno de `HOORAY`, mas tem aspas quando usado na variável. Há um motivo para isso:
>
> * Quando você usa `content` diretamente na mutação, o esquema espera que o valor seja do tipo [`ReactionContent`](/pt/enterprise-server@3.22/graphql/reference/reactions#enum-reactioncontent), que é uma *enumeração*, não uma cadeia de caracteres. A validação de esquema causará um erro se você adicionar aspas no valor do enum, já que as aspas são reservadas para strings.
> * Ao usar `content` em uma variável, a seção de variáveis precisa ser um JSON válido. Portanto, as aspas são obrigatórias. A validação de esquema interpreta corretamente o tipo `ReactionContent` quando a variável é passada para a mutação durante a execução.
>
> Para obter mais informações sobre a diferença entre enumerações e cadeias de caracteres, confira a [especificação oficial do GraphQL](https://spec.graphql.org/June2018/#sec-Enums).

## Leitura adicional

Há *muito* mais que você pode fazer ao formar chamadas no GraphQL. Aqui estão alguns lugares para considerar a seguir:

* [Como usar paginação na API GraphQL](/pt/enterprise-server@3.22/graphql/guides/using-pagination-in-the-graphql-api)
* [Fragmentos](https://graphql.org/learn/queries/#fragments)
* [Fragmentos em linha](https://graphql.org/learn/queries/#inline-fragments)
* [Diretivas](https://graphql.org/learn/queries/#directives)