Удаление поля из ответа
Добавление директивы @remove в схему GraphQL, которая удаляет вывод поля из ответа.
Описание
Спецификация GraphQL указывает, что ответ GraphQL должен точно соответствовать форме запроса. Однако в некоторых случаях мы предпочитаем не возвращать ответ поля, потому что:
- Мы уже знаем его значение, и отказавшись от повторной отправки, можно повысить производительность
- Оно содержит конфиденциальную информацию (например, учётные данные для входа)
- Пустое поле можно отличить от значения
null
Добавив @remove к полю, оно не будет выведено в ответе.
В приведённом ниже запросе (использующем расширения PHP Functions via Schema и HTTP Client) мы формируем URL для отправки HTTP-запроса, конкатенируя домен сайта и endpoint REST API. Поскольку значения этих «компонентов» нас не интересуют, их не нужно выводить в ответе, и мы можем убрать их с помощью @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
}
)
}...в результате (обратите внимание, что поля siteURL и requestURL отсутствуют в ответе):
{
"data": {
"_sendJSONObjectItemHTTPRequest": {
"id": 11,
"date": "2020-12-12T04:07:36",
"content": {
"rendered": "<p>Btw, I really like this stuff<\/p>\n"
}
}
}
}Можно также указать директиве @remove удалять значение условно — при выполнении определённого условия. Аргумент condition принимает 3 возможных значения:
ALWAYS(значение по умолчанию): удалять всегдаIS_NULL: удалять, когда значение равноnullIS_EMPTY: удалять, когда значение пустое
Например, в приведённом ниже запросе, если у записи нет избранного изображения, поле featuredImage будет иметь значение null. Добавив @remove(condition: IS_NULL), это значение не попадёт в ответ:
query {
posts {
title
featuredImage @remove(condition: IS_NULL) {
src
}
}
}...в результате:
{
"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"
}
]
}
}Примеры
Удаление ненужных данных из внешнего API
Предположим, нам нужно получить определённые данные из внешнего endpoint REST API, а остальные данные не нужны. Мы можем использовать @remove, чтобы уменьшить размер полезной нагрузки ответа и тем самым повысить производительность:
- Использовать поле
_sendJSONObjectItemHTTPRequest(из расширения HTTP Client) для подключения к REST API - Обработать данные, чтобы извлечь нужную часть информации (с помощью Field to Input и поля
_objectPropertyиз PHP Function via Schema) - Убрать исходные данные из endpoint REST с помощью
@remove
Следующий запрос объединяет всё это:
{
postData: _sendJSONObjectItemHTTPRequest(input: {
url: "https://newapi.getpop.org/wp-json/wp/v2/posts/1"
}) @remove
renderedTitle: _objectProperty(
object: $__postData,
by: {
path: "title.rendered"
}
)
}В ответе на этот запрос поле postData удалено:
{
"data": {
"renderedTitle": "Hello world!"
}
}Исключение учётных данных пользователя из вывода
Этот пример подключается к API GitHub для получения артефактов из приватного репозитория и исключает учётные данные пользователя из ответа:
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 }
}
)
}Спецификация GraphQL
Данная функциональность в настоящее время не входит в спецификацию GraphQL, однако соответствующий запрос был сделан: