如何使Shopware 6 Store-API开放未标记为API感知的实体字段?
如何将未标记API感知的实体字段开放至Shopware 6 Store-API
当然可以实现,核心是通过自定义插件修改实体字段的API感知属性,并扩展Store API的返回结构体,以下是具体步骤(以商品的visibilities关联字段为例):
1. 修改实体字段的API感知设置
Shopware通过实体字段的apiAware属性控制是否对API开放,你可以通过事件订阅器修改目标字段的该属性,避免直接修改核心代码:
use Shopware\Core\Content\Product\ProductDefinition; use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDefinitionEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ProductApiFieldSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ EntityDefinitionEvent::class => 'onEntityDefinitionBuild', ]; } public function onEntityDefinitionBuild(EntityDefinitionEvent $event): void { $definition = $event->getDefinition(ProductDefinition::class); if (!$definition) { return; } $visibilitiesField = $definition->getField('visibilities'); if ($visibilitiesField) { $visibilitiesField->setApiAware(true); } } }
2. 扩展Store API的返回结构体并注入数据
仅开启apiAware还不够,需要确保Store API的返回结构体包含该字段,同时在数据查询时加载关联关系:
方式一:通过路由装饰器加载关联并注入字段
以商品详情路由为例,装饰ProductDetailRoute来添加关联查询并注入visibilities数据:
use Shopware\Core\Content\Product\SalesChannel\Detail\ProductDetailRoute; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Symfony\Component\HttpFoundation\Request; class ExtendedProductDetailRoute extends ProductDetailRoute { public function load(string $productId, Request $request, SalesChannelContext $context, Criteria $criteria): array { // 添加visibilities关联查询 $criteria->addAssociation('visibilities'); $result = parent::load($productId, $request, $context, $criteria); $product = $result['product']; // 将visibilities数据注入返回的结构体 $product->addExtension('visibilities', $product->getVisibilities()); return $result; } }
方式二:通过事件监听注入字段
使用ProductListingResultLoadedEvent或ProductDetailResultLoadedEvent,在数据返回前注入字段:
use Shopware\Core\Content\Product\SalesChannel\Event\ProductDetailResultLoadedEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ProductApiDataInjector implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ ProductDetailResultLoadedEvent::class => 'onProductDetailLoaded', ]; } public function onProductDetailLoaded(ProductDetailResultLoadedEvent $event): void { $product = $event->getResult(); // 确保关联已加载,若未加载可在此处触发查询 $visibilities = $product->getVisibilities(); $product->addExtension('visibilities', $visibilities); } }
注意事项
- 所有修改必须通过自定义插件实现,禁止直接修改Shopware核心文件,避免版本升级时丢失配置
- 需添加权限校验:确保调用Store API的请求拥有访问该字段的权限,可在路由或事件中加入权限判断
- 关联字段需确保查询时已加载:若未通过
addAssociation加载关联数据,即使开启apiAware也无法返回有效内容
内容的提问来源于stack exchange,提问作者Paweł Napierała
相关产品推荐
相关产品推荐

