Install the Product Glue API

Edit on GitHub

Follow the steps below to integrate the Glue API: Products feature.

Prerequisites

Install the required features:

NAME VERSION INSTALLATION GUIDE
Spryker Core 202404.0 Install the Spryker Core Glue API
Product 202404.0
Price 202404.0

1) Install the required modules

Run the following command to install the required modules:

composer require spryker/products-rest-api:"^2.11.0" spryker/product-image-sets-rest-api:"^1.0.3" spryker/product-prices-rest-api:"^1.1.0" spryker/product-tax-sets-rest-api:"^2.1.2" spryker/products-categories-resource-relationship:"^1.0.0" spryker/product-attributes-rest-api:"^1.0.0" --update-with-dependencies
Verification

Make sure that the following modules have been installed:

MODULE EXPECTED DIRECTORY
ProductsRestApi vendor/spryker/products-rest-api
ProductImageSetsRestApi vendor/spryker/product-image-sets-rest-api
ProductPricesRestApi vendor/spryker/product-prices-rest-api
ProductTaxSetsRestApi vendor/spryker/product-tax-sets-rest-api
ProductsCategoriesResourceRelationship vendor/spryker/products-categories-resource-relationship
ProductAttributesRestApi vendor/spryker/product-attributes-rest-api

2) Set up configuration

You can control whether the abstract-products get the concrete-products as a relationship by default with the ProductsRestApiConfig::ALLOW_PRODUCT_CONCRETE_EAGER_RELATIONSHIP config setting.

src/Pyz/Glue/ProductsRestApi/ProductsRestApiConfig.php

<?php

namespace Pyz\Glue\ProductsRestApi;

use Spryker\Glue\ProductsRestApi\ProductsRestApiConfig as SprykerProductsRestApiConfig;

class ProductsRestApiConfig extends SprykerProductsRestApiConfig
{
    public const ALLOW_PRODUCT_CONCRETE_EAGER_RELATIONSHIP = false;
}

We recommend setting ALLOW_PRODUCT_CONCRETE_EAGER_RELATIONSHIP to false.  

Using ALLOW_PRODUCT_CONCRETE_EAGER_RELATIONSHIP = true in combination with ConcreteProductsByProductConcreteIdsResourceRelationshipPlugin, which is described later in this document, results in duplicated relationships.

We also recommend using ConcreteProductsByProductConcreteIdsResourceRelationshipPlugin with ALLOW_PRODUCT_CONCRETE_EAGER_RELATIONSHIP = false. The config setting exists for BC reasons only.

3) Set up database schema and transfer objects

Run the following commands to update the database and generate entity and transfer changes:

console propel:install
console transfer:generate
Verification

Ensure that the following changes have occurred in transfer objects:

TRANSFER TYPE EVENT PATH
AbstractProductsRestAttributesTransfer class created src/Generated/Shared/Transfer/AbstractProductsRestAttributesTransfer
ConcreteProductsRestAttributesTransfer class created src/Generated/Shared/Transfer/ConcreteProductsRestAttributesTransfer
RestProductImageSetsAttributesTransfer class created src/Generated/Shared/Transfer/RestProductImageSetsAttributesTransfer
RestProductImageSetTransfer class created src/Generated/Shared/Transfer/RestProductImageSetTransfer
RestImagesAttributesTransfer class created src/Generated/Shared/Transfer/RestImagesAttributesTransfer
RestProductPriceAttributesTransfer class created src/Generated/Shared/Transfer/RestProductPriceAttributesTransfer
RestProductPricesAttributesTransfer class created src/Generated/Shared/Transfer/RestProductPricesAttributesTransfer
RestCurrencyTransfer class created src/Generated/Shared/Transfer/RestCurrencyTransfer
RestProductManagementAttributeAttributes class created src/Generated/Shared/Transfer/RestProductManagementAttributeAttributesTransfer
RestLocalizedProductManagementAttributeKeyAttributes class created src/Generated/Shared/Transfer/RestLocalizedProductManagementAttributeKeyAttributesTransfer
RestProductManagementAttributeValueAttributes class created src/Generated/Shared/Transfer/RestProductManagementAttributeValueAttributesTransfer
RestProductManagementAttributeValueTranslationAttributes class created src/Generated/Shared/Transfer/RestProductManagementAttributeValueTranslationAttributesTransfer
Verification

Ensure that SpyProductAbstractStorage and SpyProductConcreteStorage are extended with the synchronization behavior of the following methods:

ENTITY TYPE EVENT PATH METHODS
SpyProductAbstractStorage class extended src/Orm/Zed/ProductStorage/Persistence/Base/SpyProductAbstractStorage syncPublishedMessageForMappings(), syncUnpublishedMessageForMappings()
SpyProductConcreteStorage class extended src/Orm/Zed/ProductStorage/Persistence/Base/SpyProductConcreteStorage syncPublishedMessageForMappings(), syncUnpublishedMessageForMappings()

4) Set up behavior

Set up the following behaviors.

Re-export data to storage

Run the following commands to reload the abstract and concrete product data into the Storage:

console publish:trigger-events -r product_abstract
console publish:trigger-events -r product_concrete
Verification

Ensure that the following Redis keys exist, and there is data in them:

  • kv:product_abstract:{{store_name}}:{{locale_name}}:sku:{{sku_product_abstract}}

  • kv:product_concrete:{{locale_name}}:sku:{{sku_product_concrete}}

Enable resources

Activate the following plugins:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AbstractProductsResourceRoutePlugin Registers the abstract-products resource. None Spryker\Glue\ProductsRestApi\Plugin
ConcreteProductsResourceRoutePlugin Registers the concrete-products resource. None Spryker\Glue\ProductsRestApi\Plugin

src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php

<?php

namespace Pyz\Glue\GlueApplication;

use Spryker\Glue\GlueApplication\GlueApplicationDependencyProvider as SprykerGlueApplicationDependencyProvider;
use Spryker\Glue\ProductsRestApi\Plugin\AbstractProductsResourceRoutePlugin;
use Spryker\Glue\ProductsRestApi\Plugin\ConcreteProductsResourceRoutePlugin;

class GlueApplicationDependencyProvider extends SprykerGlueApplicationDependencyProvider
{
    /**
     * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRoutePluginInterface[]
     */
    protected function getResourceRoutePlugins(): array
    {
        return [
            new AbstractProductsResourceRoutePlugin(),
			new ConcreteProductsResourceRoutePlugin(),
        ];
    }
}
Verification

Ensure that the following endpoints are available:

  • https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}

  • https://glue.mysprykershop.com/concrete-products/{{concrete_sku}}

Enable relationships

Activate the following plugins:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
ConcreteProductsByProductConcreteIdsResourceRelationshipPlugin Adds the concrete-products resource as a relationship to the abstract-products resource. None Spryker\Glue\ProductsRestApi\Plugin\GlueApplication
ProductAbstractByProductAbstractSkuResourceRelationshipPlugin Adds the abstract-products resource as a relationship to the concrete-products resource. None Spryker\Glue\ProductsRestApi\Plugin\GlueApplication

src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php

<?php

namespace Pyz\Glue\GlueApplication;

use Spryker\Glue\GlueApplication\GlueApplicationDependencyProvider as SprykerGlueApplicationDependencyProvider;
use Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface;
use Spryker\Glue\ProductsRestApi\Plugin\GlueApplication\ConcreteProductsByProductConcreteIdsResourceRelationshipPlugin;
use Spryker\Glue\ProductsRestApi\Plugin\GlueApplication\ProductAbstractByProductAbstractSkuResourceRelationshipPlugin;
use Spryker\Glue\ProductsRestApi\ProductsRestApiConfig;

class GlueApplicationDependencyProvider extends SprykerGlueApplicationDependencyProvider
{
    /**
     * @param \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface $resourceRelationshipCollection
     *
     * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface
     */
    protected function getResourceRelationshipPlugins(
        ResourceRelationshipCollectionInterface $resourceRelationshipCollection
    ): ResourceRelationshipCollectionInterface {
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_ABSTRACT_PRODUCTS,
            new ConcreteProductsByProductConcreteIdsResourceRelationshipPlugin()
        );
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_CONCRETE_PRODUCTS,
            new ProductAbstractByProductAbstractSkuResourceRelationshipPlugin()
        );

        return $resourceRelationshipCollection;
    }
}
Verification

Ensure that:

  • The following endpoints are available:

  • When the concrete-products resource is included as a query string, the abstract-products resource returns it as a relationship: https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}?include=concrete-products.

  • When the abstract-products resource is included as a query string, the concrete-products resource returns it as a relationship: https://glue.mysprykershop.com/concrete-products/{{concrete_sku}}?include=abstract-products.

Enable resources and relationships of image sets

Activate the following plugins:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AbstractProductImageSetsRoutePlugin Registers the abstract-product-image-sets resource. None Spryker\Glue\ProductImageSetsRestApi\Plugin
ConcreteProductImageSetsRoutePlugin Registers the concrete-product-image-sets resource. None Spryker\Glue\ProductImageSetsRestApi\Plugin
AbstractProductsProductImageSetsResourceRelationshipPlugin Adds the abstract-product-image-sets resource as a relationship to the abstract-products resource. None Spryker\Glue\ProductImageSetsRestApi\Plugin\Relationship
ConcreteProductsProductImageSetsResourceRelationshipPlugin Adds the concrete-product-image-sets resource as a relationship to the concrete-products resource. None Spryker\Glue\ProductImageSetsRestApi\Plugin\Relationship
src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php
<?php

namespace Pyz\Glue\GlueApplication;

use Spryker\Glue\GlueApplication\GlueApplicationDependencyProvider as SprykerGlueApplicationDependencyProvider;
use Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface;
use Spryker\Glue\ProductImageSetsRestApi\Plugin\AbstractProductImageSetsRoutePlugin;
use Spryker\Glue\ProductImageSetsRestApi\Plugin\ConcreteProductImageSetsRoutePlugin;
use Spryker\Glue\ProductImageSetsRestApi\Plugin\Relationship\AbstractProductsProductImageSetsResourceRelationshipPlugin;
use Spryker\Glue\ProductImageSetsRestApi\Plugin\Relationship\ConcreteProductsProductImageSetsResourceRelationshipPlugin;
use Spryker\Glue\ProductsRestApi\ProductsRestApiConfig;

class GlueApplicationDependencyProvider extends SprykerGlueApplicationDependencyProvider
{
    /**
     * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRoutePluginInterface[]
     */
    protected function getResourceRoutePlugins(): array
    {
        return [
            new AbstractProductImageSetsRoutePlugin(),
			new ConcreteProductImageSetsRoutePlugin(),
        ];
    }

 	/**
    * @param \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface $resourceRelationshipCollection
    *
    * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface
    */
    protected function getResourceRelationshipPlugins(
        ResourceRelationshipCollectionInterface $resourceRelationshipCollection
    ): ResourceRelationshipCollectionInterface {
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_ABSTRACT_PRODUCTS,
            new AbstractProductsProductImageSetsResourceRelationshipPlugin()
        );
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_CONCRETE_PRODUCTS,
            new ConcreteProductsProductImageSetsResourceRelationshipPlugin()
        );

        return $resourceRelationshipCollection;
    }
}
Verification

Ensure the following:

  • The endpoints are available:

    • https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}/abstract-product-image-sets

    • https://glue.mysprykershop.com/concrete-products/{{concrete_sku}}/concrete-product-image-sets

  • When the abstract-product-image-sets resource is included as a query string, the abstract-products resource returns it as a relationship: https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}?include=abstract-product-image-sets

  • When the concrete-product-image-sets resource is included as a query string, the concrete-products resource returns it as a relationship: https://glue.mysprykershop.com/concrete-products/{{abstract_sku}}?include=concrete-product-image-sets

Enable resources and relationships of prices

Activate the following plugins:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AbstractProductPricesRoutePlugin Registers the abstract-product-prices resource. None Spryker\Glue\ProductPricesRestApi\Plugin
ConcreteProductPricesRoutePlugin Registers the concrete-product-prices resource. None Spryker\Glue\ProductPricesRestApi\Plugin
AbstractProductPricesByResourceIdResourceRelationshipPlugin Adds the abstract-product-prices-resource as a relationship to the abstract-products resource. None Spryker\Glue\ProductPricesRestApi\Plugin\GlueApplication
ConcreteProductPricesByResourceIdResourceRelationshipPlugin Adds the concrete-product-prices-resource as a relationship to the concrete-products resource. None Spryker\Glue\ProductPricesRestApi\Plugin\GlueApplication
src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php
<?php

namespace Pyz\Glue\GlueApplication;

use Spryker\Glue\GlueApplication\GlueApplicationDependencyProvider as SprykerGlueApplicationDependencyProvider;
use Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface;
use Spryker\Glue\ProductPricesRestApi\Plugin\AbstractProductPricesRoutePlugin;
use Spryker\Glue\ProductPricesRestApi\Plugin\ConcreteProductPricesRoutePlugin;
use Spryker\Glue\ProductPricesRestApi\Plugin\GlueApplication\AbstractProductPricesByResourceIdResourceRelationshipPlugin;
use Spryker\Glue\ProductPricesRestApi\Plugin\GlueApplication\ConcreteProductPricesByResourceIdResourceRelationshipPlugin;
use Spryker\Glue\ProductsRestApi\ProductsRestApiConfig;

class GlueApplicationDependencyProvider extends SprykerGlueApplicationDependencyProvider
{
    /**
     * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRoutePluginInterface[]
     */
    protected function getResourceRoutePlugins(): array
    {
        return [
            new AbstractProductPricesRoutePlugin(),
            new ConcreteProductPricesRoutePlugin(),
        ];
    }

    /**
     * @param \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface $resourceRelationshipCollection
     *
     * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface
     */
    protected function getResourceRelationshipPlugins(
        ResourceRelationshipCollectionInterface $resourceRelationshipCollection
    ): ResourceRelationshipCollectionInterface {
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_ABSTRACT_PRODUCTS,
            new AbstractProductPricesByResourceIdResourceRelationshipPlugin()
        );
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_CONCRETE_PRODUCTS,
            new ConcreteProductPricesByResourceIdResourceRelationshipPlugin()
        );

        return $resourceRelationshipCollection;
    }
}
Verification

Ensure the following:

  • The endpoints are available:

    • https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}/abstract-product-prices

    • https://glue.mysprykershop.com/concrete-products/{{concrete_sku}}/concrete-product-prices

  • When the abstract-product-prices resource is included as a query string, the abstract-products resource returns it as a relationship: https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}?include=abstract-product-prices

  • When the concrete-product-prices resource is included as a query string, the concrete-products resource returns it as a relationship: https://glue.mysprykershop.com/concrete-products/{{abstract_sku}}?include=concrete-product-prices

Enable resources and relationships of category

Activate the following plugin:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AbstractProductsCategoriesResourceRelationshipPlugin Adds the categories resource as a relationship to the abstract-products resource. None Spryker\Glue\ProductsCategoriesResourceRelationship\Plugin

src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php

<?php

namespace Pyz\Glue\GlueApplication;

use Spryker\Glue\GlueApplication\GlueApplicationDependencyProvider as SprykerGlueApplicationDependencyProvider;
use Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface;
use Spryker\Glue\ProductsCategoriesResourceRelationship\Plugin\AbstractProductsCategoriesResourceRelationshipPlugin;
use Spryker\Glue\ProductsRestApi\ProductsRestApiConfig;

class GlueApplicationDependencyProvider extends SprykerGlueApplicationDependencyProvider
{
   /**
    * @param \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface $resourceRelationshipCollection
    *
    * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRelationshipCollectionInterface
    */
    protected function getResourceRelationshipPlugins(
        ResourceRelationshipCollectionInterface $resourceRelationshipCollection
    ): ResourceRelationshipCollectionInterface {
        $resourceRelationshipCollection->addRelationship(
            ProductsRestApiConfig::RESOURCE_ABSTRACT_PRODUCTS,
            new AbstractProductsCategoriesResourceRelationshipPlugin()
        );

        return $resourceRelationshipCollection;
    }
}
Verification

Ensure that the relationship has been registered correctly:

  1. Send a request to https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}?include=category-nodes.

  2. The response should contain the category-nodes resource as a relationship.

Response sample
{  
   "data":{  
      "type":"abstract-products",
      "id":"001",
      "attributes":{  
         ...
      },
      "links":{  
         "self":"https://glue.mysprykershop.com/abstract-products/001"
      },
      "relationships":{  
         "category-nodes":{  
            "data":[  
               {  
                  "type":"category-nodes",
                  "id":"4"
               },
               {  
                  "type":"category-nodes",
                  "id":"2"
               }
            ]
         }
      }
   },
   "included":[  
      {  
         "type":"category-nodes",
         "id":"4",
         "attributes":{  
            ...
         },
         "links":{  
            "self":"https://glue.mysprykershop.com/category-nodes/4"
         }
      },
      {  
         "type":"category-nodes",
         "id":"2",
         "attributes":{  
            ...
         },
         "links":{  
            "self":"https://glue.mysprykershop.com/category-nodes/2"
         }
      }
   ]
}

Enable resources and relationships of product management attributes

Activate the following plugin:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
ProductManagementAttributesResourceRoutePlugin Registers the product-management-attributes resource. None Spryker\Glue\ProductAttributesRestApi\Plugin\GlueApplication

src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php

<?php

namespace Pyz\Glue\GlueApplication;

use Spryker\Glue\GlueApplication\GlueApplicationDependencyProvider as SprykerGlueApplicationDependencyProvider;
use Spryker\Glue\ProductAttributesRestApi\Plugin\GlueApplication\ProductManagementAttributesResourceRoutePlugin;

class GlueApplicationDependencyProvider extends SprykerGlueApplicationDependencyProvider
{
    /**
     * @return \Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRoutePluginInterface[]
     */
    protected function getResourceRoutePlugins(): array
    {
        return [
			new ProductManagementAttributesResourceRoutePlugin(),
        ];
    }
}
Verification

Ensure that the following endpoint is available: https://glue.mysprykershop.com/product-management-attributes/{{attribute_key}}