Eliminación de la Respuesta de un Campo
Adición de la directiva @remove al esquema GraphQL, que elimina la salida de un campo de la respuesta.
Descripción
La especificación de GraphQL indica que la respuesta de GraphQL debe coincidir exactamente con la forma de la consulta. Sin embargo, en ciertas circunstancias preferimos evitar devolver la respuesta del campo, porque:
- Ya sabemos cuál es, y al no enviarla de nuevo podemos mejorar el rendimiento
- Contiene información sensible (como credenciales de inicio de sesión)
- Un campo vacío puede distinguirse de un valor
null
Añadiendo @remove al campo, no se imprimirá en la respuesta.
En la consulta de abajo (que usa las extensiones PHP Functions via Schema y HTTP Client), generamos la URL a la que enviar una petición HTTP, concatenando el dominio del sitio y el endpoint de la API REST. Como los valores de estos "componentes" no nos interesan, no hay necesidad de imprimirlos en la respuesta, y podemos eliminarlos con @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
}
)
}...produciendo (nótese que los campos siteURL y requestURL no están en la respuesta):
{
"data": {
"_sendJSONObjectItemHTTPRequest": {
"id": 11,
"date": "2020-12-12T04:07:36",
"content": {
"rendered": "<p>Btw, I really like this stuff<\/p>\n"
}
}
}
}También podemos indicarle a la directiva @remove que elimine el valor condicionalmente, si se cumple una condición. El argumento condition puede recibir 3 valores posibles:
ALWAYS(valor por defecto): Eliminarlo siempreIS_NULL: Eliminarlo siempre que el valor seanullIS_EMPTY: Eliminarlo siempre que el valor esté vacío
Por ejemplo, en la consulta de abajo, cuando una entrada no tiene imagen destacada, el campo featuredImage tendrá valor null. Añadiendo @remove(condition: IS_NULL), este valor no se añadirá a la respuesta:
query {
posts {
title
featuredImage @remove(condition: IS_NULL) {
src
}
}
}...produciendo:
{
"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"
}
]
}
}Ejemplos
Eliminar datos innecesarios de una API externa
Supongamos que queremos recuperar algunos datos específicos de un endpoint de API REST externo, y no necesitamos el resto de los datos. Podemos entonces usar @remove para hacer el payload de la respuesta más pequeño, mejorando así el rendimiento:
- Usar el campo
_sendJSONObjectItemHTTPRequest(de la extensión HTTP Client) para conectarse a la API REST - Procesar estos datos para extraer la pieza de información necesaria (mediante Field to Input y el campo
_objectPropertyde PHP Function via Schema) - Eliminar con
@removelos datos originales del endpoint REST
Esta consulta lo une todo:
{
postData: _sendJSONObjectItemHTTPRequest(input: {
url: "https://newapi.getpop.org/wp-json/wp/v2/posts/1"
}) @remove
renderedTitle: _objectProperty(
object: $__postData,
by: {
path: "title.rendered"
}
)
}En la respuesta a esta consulta, el campo postData ha sido eliminado:
{
"data": {
"renderedTitle": "Hello world!"
}
}Evitar imprimir credenciales de usuario
Este ejemplo se conecta a la API de GitHub para recuperar los artefactos disponibles en un repositorio privado, y evita imprimir las credenciales del usuario en la respuesta:
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 }
}
)
}Especificación de GraphQL
Esta funcionalidad no forma parte actualmente de la especificación de GraphQL, pero se ha solicitado: