Query Functions
Query FunctionsRemoção da Resposta de um Campo

Remoção da Resposta de um Campo

Included in the “Power Extensions” bundle

Adição da diretiva @remove ao schema GraphQL, que remove o output de um campo da resposta.

Descrição

A especificação GraphQL indica que a resposta GraphQL deve corresponder exatamente ao formato da query. No entanto, em determinadas circunstâncias preferimos evitar retornar a resposta do campo, porque:

  • Já sabemos qual é o valor e, ao não reenviá-lo, podemos melhorar o desempenho
  • Ele contém informações sensíveis (como credenciais de acesso)
  • Um campo vazio pode ser distinguido de um valor null

Ao adicionar @remove ao campo, ele não será incluído na resposta.

Na query abaixo (que usa as extensões PHP Functions via Schema e HTTP Client), geramos a URL para enviar uma requisição HTTP, concatenando o domínio do site e o endpoint da API REST. Como os valores desses "componentes" não nos interessam, não há necessidade de incluí-los na resposta e podemos removê-los com @remove:

query {
  siteURL: optionValue(name: "siteurl")
    @remove
 
  requestURL: _sprintf(
    string: "%s/wp-json/wp/v2/comments/11/?_fields=id,content,date",
    values: [$__siteURL]
  )
    @remove
 
  _sendJSONObjectItemHTTPRequest(
    input: {
      url: $__requestURL
    }
  )
}

...produzindo (observe que os campos siteURL e requestURL não estão na resposta):

{
  "data": {
    "_sendJSONObjectItemHTTPRequest": {
      "id": 11,
      "date": "2020-12-12T04:07:36",
      "content": {
        "rendered": "<p>Btw, I really like this stuff<\/p>\n"
      }
    }
  }
}

Também podemos instruir a diretiva @remove a remover o valor de forma condicional, se uma condição for atendida. O argumento condition pode receber 3 valores possíveis:

  • ALWAYS (valor padrão): Remover sempre
  • IS_NULL: Remover sempre que o valor for null
  • IS_EMPTY: Remover sempre que o valor estiver vazio

Por exemplo, na query abaixo, quando um post não tem uma imagem destacada, o campo featuredImage terá o valor null. Ao adicionar @remove(condition: IS_NULL), esse valor não será adicionado à resposta:

query {
  posts {
    title
    featuredImage @remove(condition: IS_NULL) {
      src
    }
  }
}

...produzindo:

{
  "data": {
    "posts": [
      {
        "title": "Hello world!"
      },
      {
        "title": "Nested mutations are a must have",
        "featuredImage": {
          "src": "https:\/\/gato-graphql.lndo.site\/wp-content\/uploads\/2022\/05\/graphql-voyager-public.jpg"
        }
      },
      {
        "title": "Customize the schema for each client"
      }
    ]
  }
}

Exemplos

Remover dados desnecessários de uma API externa

Suponha que queremos recuperar alguns dados específicos de um endpoint de uma API REST externa e não precisamos do restante dos dados. Podemos então usar @remove para reduzir o tamanho do payload da resposta, melhorando assim o desempenho:

  • Usar o campo _sendJSONObjectItemHTTPRequest (da extensão HTTP Client) para conectar à API REST
  • Processar esses dados para extrair a informação necessária (via Field to Input e o campo _objectProperty de PHP Function via Schema)
  • Remover com @remove os dados originais do endpoint REST

Esta query une tudo isso:

{
  postData: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://newapi.getpop.org/wp-json/wp/v2/posts/1"
  }) @remove
  renderedTitle: _objectProperty(
    object: $__postData,
    by: {
      path: "title.rendered"
    }
  )
}

Na resposta a esta query, o campo postData foi removido:

{
  "data": {
    "renderedTitle": "Hello world!"
  }
}

Evitar a exibição das credenciais do usuário

Este exemplo conecta à API do GitHub para recuperar os artefatos disponíveis em um repositório privado, e evita exibir as credenciais do usuário na resposta:

query RetrieveGitHubActionArtifacts(
  $repoOwner: String!
  $repoProject: String!
) {
  githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
    @remove
 
  # Create the authorization header to send to GitHub
  authorizationHeader: _sprintf(
    string: "Bearer %s"
    # "Field to Input" feature to access value from the field above
    values: [$__githubAccessToken]
  )
    @remove
 
  # Create the authorization header to send to GitHub
  githubRequestHeaders: _echo(
    value: [
      { name: "Accept", value: "application/vnd.github+json" }
      { name: "Authorization", value: $__authorizationHeader }
    ]
  )
    @remove
 
  githubAPIEndpoint: _sprintf(
    string: "https://api.github.com/repos/%s/%s/actions/artifacts"
    values: [$repoOwner, $repoProject]
  )
 
  # Use the field from "Send HTTP Request Fields" to connect to GitHub
  gitHubArtifactData: _sendJSONObjectItemHTTPRequest(
    input: {
      url: $__githubAPIEndpoint
      options: { headers: $__githubRequestHeaders }
    }
  )
}

Especificação GraphQL

Esta funcionalidade atualmente não faz parte da especificação GraphQL, mas foi solicitada: