Search code examples
shopware

Shopware 6 - add custom data to product entity with addExtension and make them appear in store-api responses


Within a subscriber to the ProductListingResultEvent::class I use the addExtension method to add some custom data to the product entity:

$product->addExtension('myExtension, new ArrayStruct(['foo' => 'bar']));

This works ok, the data are added to the product entity structure. But the response of a store-api/product-listing request does not show the data:

{
    "elements": [
        {
            "extensions": {
                "search": {
                    "extensions": [],
                    "_uniqueIdentifier": null,
                    "translated": [],
                    "id": "018d4c57dad8727eace966d4efa56c3f",
                    "productNumber": "XYZ",
                    "autoIncrement": 369
                }
            },
...

However I want the data to show up in the response like this:

{
    "elements": [
        {
            "extensions": {
                "search": {
                    "extensions": [],
                    "_uniqueIdentifier": null,
                    "translated": [],
                    "id": "018d4c57dad8727eace966d4efa56c3f",
                    "productNumber": "XYZ",
                    "autoIncrement": 369
                },
                "myExtension": {
                    "apiAlias": "array_struct",
                    "foo": "bar"
                }
            },

How can I achieve this? Is it somehow possible to set a flag ApiAware for a dynamic extension?


Solution

  • Have you tried creating an entity extension for the product definition and adding your field with the the Runtime and ApiAware flag?

    For example:

    class ProductExtension extends EntityExtension
    {
        public function extendFields(FieldCollection $collection): void
        {
            $collection->add(
                (new JsonField('myExtension', 'myExtension'))->addFlags(new ApiAware(), new Runtime())
            );
        }
    
        public function getDefinitionClass(): string
        {
            return ProductDefinition::class;
        }
    }