Drupal:如何通过JSON:API模块将JSON Config暴露为结构化API?
在Drupal 8/9/10中让JSON字段以结构化格式通过JSON:API返回
方法一:通过JSON:API钩子直接修改字段输出
这种方式无需创建额外格式化器,适合快速解决单个字段的序列化问题:
- 创建或使用现有自定义模块,在模块的
.module文件中添加以下代码:
<?php /** * Implements hook_jsonapi_normalizer_alter(). */ function your_module_name_jsonapi_normalizer_alter(array &$normalized, \Drupal\Core\Entity\EntityInterface $entity, \Symfony\Component\Serializer\Normalizer\NormalizerInterface $normalizer, $format, array $context) { // 匹配你的内容类型和字段名 if ($entity->getEntityTypeId() === 'node' && $entity->bundle() === 'json_page' && isset($normalized['field_json_config'])) { foreach ($normalized['field_json_config'] as &$item) { if (isset($item['value'])) { $decoded = json_decode($item['value'], TRUE); // 验证JSON解析是否成功 if (json_last_error() === JSON_ERROR_NONE) { // 替换原字符串值为结构化数据 unset($item['value']); $item = array_merge($item, $decoded); } } } } }
- 替换代码中的
your_module_name为你的自定义模块名称,json_page为内容类型机器名。 - 启用模块后,重新请求JSON:API接口,
field_json_config字段将返回结构化的JSON对象/数组。
方法二:自定义字段格式化器(更规范的复用方案)
如果需要在多个字段或内容类型中复用,推荐创建自定义格式化器:
步骤1:创建自定义模块结构
新建模块json_structured_serializer,包含以下文件:
json_structured_serializer.info.ymljson_structured_serializer.modulesrc/Plugin/Field/FieldFormatter/JsonStructuredFormatter.phpsrc/Serializer/JsonStructuredSerializer.php
模块信息文件(json_structured_serializer.info.yml)
name: 'Structured JSON Field Serializer' type: module description: 'Adds structured JSON serialization for fields in JSON:API' core_version_requirement: ^8 || ^9 || ^10 package: Custom dependencies: - drupal:jsonapi
自定义字段格式化器(src/Plugin/Field/FieldFormatter/JsonStructuredFormatter.php)
<?php namespace Drupal\json_structured_serializer\Plugin\Field\FieldFormatter; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FormatterBase; /** * Plugin implementation of the 'json_structured' formatter. * * @FieldFormatter( * id = "json_structured", * label = @Translation("Structured JSON"), * field_types = {"string_long", "json"} * ) */ class JsonStructuredFormatter extends FormatterBase { /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = []; foreach ($items as $delta => $item) { $decoded = json_decode($item->value, TRUE); if (json_last_error() === JSON_ERROR_NONE) { $elements[$delta] = ['#value' => $decoded]; } else { $elements[$delta] = ['#plain_text' => $item->value]; } } return $elements; } }
注册JSON:API序列化器(json_structured_serializer.module)
<?php /** * Implements hook_jsonapi_field_formatter_info_alter(). */ function json_structured_serializer_jsonapi_field_formatter_info_alter(array &$info) { $info['json_structured'] = [ 'label' => t('Structured JSON'), 'field_types' => ['string_long', 'json'], 'serializer' => 'Drupal\json_structured_serializer\Serializer\JsonStructuredSerializer', ]; }
序列化器逻辑(src/Serializer/JsonStructuredSerializer.php)
<?php namespace Drupal\json_structured_serializer\Serializer; use Drupal\Core\Field\FieldItemListInterface; use Drupal\jsonapi\Normalizer\Value\FieldItemNormalizerValue; use Drupal\jsonapi\Normalizer\Value\FieldNormalizerValue; /** * Serializes structured JSON fields for JSON:API. */ class JsonStructuredSerializer { /** * Serializes the field item list into structured data. */ public function serialize(FieldItemListInterface $items, $langcode) { $values = []; foreach ($items as $item) { $decoded = json_decode($item->value, TRUE); if (json_last_error() === JSON_ERROR_NONE) { $values[] = new FieldItemNormalizerValue($decoded); } else { $values[] = new FieldItemNormalizerValue(['value' => $item->value]); } } return new FieldNormalizerValue($values); } }
步骤2:配置字段使用自定义格式化器
- 启用
json_structured_serializer模块。 - 进入内容类型
JSON Page的字段管理页面(/admin/structure/types/manage/json_page/fields)。 - 编辑
field_json_config字段,在“格式化器”选项中选择“Structured JSON”。 - 保存配置后,访问JSON:API接口,字段将返回结构化数据。
内容的提问来源于stack exchange,提问作者Naren Karanam
相关产品推荐
相关产品推荐

