Учебник по схеме
Учебник по схемеУрок 7: Массовая адаптация контента

Урок 7: Массовая адаптация контента

Этот урок обучающего курса выполняет массовую адаптацию контента, обновляя заголовок, содержимое и анонс нескольких записей с помощью одного GraphQL-запроса.

Чтобы этот GraphQL-запрос работал, в Конфигурации схемы, применённой к эндпоинту, должны быть включены Вложенные мутации

Приведённый ниже GraphQL-запрос извлекает данные нескольких записей, выполняет поиск и замену в полях title, content и excerpt для каждой из них, преобразует их в аргументы мутации и экспортирует единственную динамическую переменную $postInputs со всеми результатами в виде словаря следующего формата:

{
  "${post ID}": {
    "title": "${adapted post title}",
    "excerpt": "${adapted post excerpt}"
  },
  // repeat for all other posts ...
}

В операции mutation каждая из этих записей извлекается через _objectProperty (используя ${post ID} в качестве ключа) и передаётся как input для обновления записи:

query TransformAndExportData(
  $limit: Int! = 5,
  $offset: Int! = 0,
  $replaceFrom: [String!]!
  $replaceTo: [String!]!
) {
  posts: posts(
    pagination: { limit: $limit, offset: $offset }
    sort: { by: ID, order: ASC }
  ) {
    rawTitle
    rawContent
    rawExcerpt
      @strReplaceMultiple(
        search: $replaceFrom
        replaceWith: $replaceTo
        affectAdditionalFieldsUnderPos: [1, 2]
      )
      @deferredExport(
        as: "postAdaptedSources"
        type: DICTIONARY
        affectAdditionalFieldsUnderPos: [1, 2]
      )
  }
}
 
query AdaptDataForMutationInput
  @depends(on: "TransformAndExportData")
{
  postInputs: _echo(value: $postAdaptedSources)
    @underEachJSONObjectProperty(
      passValueOnwardsAs: "adaptedSource",
      affectDirectivesUnderPos: [1, 2, 3, 4]
    )
      @applyField(
        name: "_objectProperty",
        arguments: {
          object: $adaptedSource,
          by: {
            key: "rawTitle"
          }
        },
        passOnwardsAs: "adaptedTitle"
      )
      @applyField(
        name: "_objectProperty",
        arguments: {
          object: $adaptedSource,
          by: {
            key: "rawExcerpt"
          }
        },
        passOnwardsAs: "adaptedExcerpt"
      )
      @applyField(
        name: "_objectProperty",
        arguments: {
          object: $adaptedSource,
          by: {
            key: "rawContent"
          }
        },
        passOnwardsAs: "adaptedContent"
      )
      @applyField(
        name: "_echo",
        arguments: {
          value: {
            title: $adaptedTitle,
            excerpt: $adaptedExcerpt,
            contentAs: {
              html: $adaptedContent
            }
          }
        },
        setResultInResponse: true
      )
    @export(as: "postInputs")
}
 
mutation UpdatePost(
  $limit: Int! = 5,
  $offset: Int! = 0
)
  @depends(on: "AdaptDataForMutationInput")
{
  adaptedPosts: posts(
    pagination: { limit: $limit, offset: $offset }
    sort: { by: ID, order: ASC }
  ) {
    id
    postInput: _objectProperty(
      object: $postInputs,
      by: { key: $__id }
    ) @remove
    update(input: $__postInput) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      post {
        title
        content
        excerpt
      }
    }
  }
}
  • Расширение Field on Field предоставляет директиву @applyField, которая при вызове с _objectProperty извлекает свойства каждого элемента JSON-объекта (переданного как $adaptedSource), а затем с помощью _echo формирует соответствующий JSON-ввод с этими свойствами
  • Помимо функциональных полей, расширение PHP Functions via Schema также предоставляет функциональность через соответствующие «функциональные директивы», такие как @strReplaceMultiple
  • Когда включена функция Мульти-поля для директив, можно применять директиву сразу к нескольким полям, указывая относительные позиции дополнительных полей через аргумент affectAdditionalFieldsUnderPos
  • При применении директивы к некоторому полю с последующим экспортом его значения необходимо использовать @deferredExport вместо @export
  • При использовании мульти-поля для директив вместе с @export (или @deferredExport) экспортируемое значение представляет собой JSON-объект, содержащий все поля
  • Мутация Post.update доступна в схеме только при включённой функции Nested Mutations