Query Functions
Query FunctionsУдаление поля из ответа

Удаление поля из ответа

Included in the “Power Extensions” bundle

Добавление директивы @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: удалять, когда значение равно null
  • IS_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, однако соответствующий запрос был сделан: