Рейтинг:1

Как я могу расширить Serializer для обработки настраиваемого типа поля?

флаг cn

я пытаюсь расширить Сериализация чтобы получить Поле JSON модуль для возврата объекта JSON вместо строкового JSON.

Цель: когда я получаю доступ к объекту, содержащему поле JSON, с помощью JSON:API, мне нужен объект JSON для значения поля (в настоящее время возвращается строковый JSON).

Я думаю, что мне нужно расширить один из основных нормализаторов и использовать его для добавления json_decode() шаг.

Существует некоторое документация о том, как Serializer обрабатывает сущности но он устарел (последний раз обновлялся в 2017 году до того, как JSON:API стал частью ядра, и текущий код не похож на то, что показано).

Я попытался расширить FieldNormalizer в /json_field/src/Normalizer/JsonFieldNormalizer.php.
Однако я не уверен, что это правильный подход, так как есть также FieldItemNormalizer и TypedDataNormalizer. Чтобы изменить способ вывода поля в JSON:API, какой класс следует расширить?

<?php

пространство имен Drupal\json_field\Normalizer;

используйте Drupal\Core\Field\FieldDefinitionInterface;
используйте Drupal\json_field\Plugin\Field\FieldType\NativeJSONItem;
используйте Drupal\jsonapi\JsonApiResource\ResourceObject;
используйте Drupal\jsonapi\Normalizer\FieldNormalizer;
используйте Drupal\jsonapi\Normalizer\Value\CacheableNormalization;
используйте Drupal\jsonapi\ResourceType\ResourceType;

класс JsonFieldNormalizer расширяет FieldNormalizer {

  /**
   * {@inheritdoc}
   */
  защищенный $supportedInterfaceOrClass = NativeJSONItem::class;

  /**
   * {@inheritdoc}
   */
  публичная функция normalize($field, $format = NULL, массив $context = []) {
    $field_name = $field->getName();
    \Drupal::logger('json_field')->info("Поле имеет имя $field_name");
    assert($field instanceof NativeJSONItem);
    /** @var \Drupal\Core\Field\FieldItemListInterface $field */ $normalized_items = $this->normalizeFieldItems($field, $format, $context);
    assert($context['resource_object'] instanceof ResourceObject);
    вернуть $context['resource_object']->getResourceType()->getFieldByInternalName($field->getName())->hasOne()
      ? array_shift($normalized_items) ?: CacheableNormalization::permanent(NULL)
      : CacheableNormalization::aggregate($normalized_items);
  }

И я добавил класс в json_field.services.yml:

Сервисы:
  json_field.просмотры:
    класс: Drupal\json_field\JSONViews
  json_field.normalizer.field.json_field:
    класс: Drupal\json_field\Normalizer\JsonFieldNormalizer
    теги:
      - {имя: нормализатор, приоритет: 1}

Однако после восстановления кеша и доступа к некоторым полям JSON через JSON:API я ничего не вижу в журналах, поэтому кажется, что класс не подхватывается.

4uk4 avatar
флаг cn
Есть несколько вещей, которые несовместимы. Вы расширяете FieldNormalizer, но $supportedInterfaceOrClass является элементом поля. Так что лучше расширить FieldItemNormalizer. Вы реализуете сериализатор jsonapi, но сервисный тег не `{ name: jsonapi_normalizer, priority: 1 }`.
флаг cn
@4uk4 Спасибо, изначально я пытался добавить его как `jsonapi_normalizer`, но когда я это сделал, я получил ошибку `LogicException: JSON:API не позволяет добавлять больше нормализаторов!` Я только что попытался расширить FieldItemNormalizer, и я получаю та же проблема (регистрация не запускается, когда я обращаюсь к полю через JSON: API).
4uk4 avatar
флаг cn
Хорошо, я только что попытался указать на несоответствия. Когда они говорят @internal, они действительно имеют это в виду. Читая комментарии в [этой проблеме] (https://www.drupal.org/project/drupal/issues/2923779), вам, вероятно, нужно добавить в свой настраиваемый тип поля также настраиваемые типизированные данные (вы можете просто расширить DataDefinition теперь вы определили в свойствах поля), а затем определите нормализатор для этого.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.