Remoção da Resposta de um Campo
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 sempreIS_NULL: Remover sempre que o valor fornullIS_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
_objectPropertyde PHP Function via Schema) - Remover com
@removeos 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: