Install the Product Glue API
Edit on GitHubThis document describes how to install the Products Glue API.
Prerequisites
Install the required features:
NAME | VERSION | INSTALLATION GUIDE |
---|---|---|
Spryker Core | 202410.0 | Install the Spryker Core Glue API |
Product | 202410.0 | |
Price | 202410.0 |
1) Install the required modules
Install the required modules using composer:
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.1.0" --update-with-dependencies
Make sure 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 backward-compatibility reasons only.
3) Set up database schema and transfer objects
Update the database and generate entity and transfer changes:
console propel:install
console transfer:generate
Ensure that the following changes have occurred in transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
AbstractProductsRestAttributes | class | created | src/Generated/Shared/Transfer/AbstractProductsRestAttributesTransfer |
ConcreteProductsRestAttributes | class | created | src/Generated/Shared/Transfer/ConcreteProductsRestAttributesTransfer |
RestProductImageSetsAttributes | class | created | src/Generated/Shared/Transfer/RestProductImageSetsAttributesTransfer |
RestProductImageSet | class | created | src/Generated/Shared/Transfer/RestProductImageSetTransfer |
RestImagesAttributes | class | created | src/Generated/Shared/Transfer/RestImagesAttributesTransfer |
RestProductPriceAttributes | class | created | src/Generated/Shared/Transfer/RestProductPriceAttributesTransfer |
RestProductPricesAttributes | class | created | src/Generated/Shared/Transfer/RestProductPricesAttributesTransfer |
RestCurrency | 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 |
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.
Reexport data to storage
Reload the abstract and concrete product data into the Storage:
console publish:trigger-events -r product_abstract
console publish:trigger-events -r product_concrete
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. |
Spryker\Glue\ProductsRestApi\Plugin | |
ConcreteProductsResourceRoutePlugin | Registers the concrete-products resource. |
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 list<\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRoutePluginInterface>
*/
protected function getResourceRoutePlugins(): array
{
return [
new AbstractProductsResourceRoutePlugin(),
new ConcreteProductsResourceRoutePlugin(),
];
}
}
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. |
Spryker\Glue\ProductsRestApi\Plugin\GlueApplication | |
ProductAbstractByProductAbstractSkuResourceRelationshipPlugin | Adds the abstract-products resource as a relationship to the concrete-products resource. |
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;
}
}
Make sure the following applies:
-
The following endpoints are available:
https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}
https://glue.mysprykershop.com/concrete-products/{{concrete_sku}}
-
When the
concrete-products
resource is included as a query string, theabstract-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, theconcrete-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. |
Spryker\Glue\ProductImageSetsRestApi\Plugin | |
ConcreteProductImageSetsRoutePlugin | Registers the concrete-product-image-sets resource. |
Spryker\Glue\ProductImageSetsRestApi\Plugin | |
AbstractProductsProductImageSetsResourceRelationshipPlugin | Adds the abstract-product-image-sets resource as a relationship to the abstract-products resource. |
Spryker\Glue\ProductImageSetsRestApi\Plugin\Relationship | |
ConcreteProductsProductImageSetsResourceRelationshipPlugin | Adds the concrete-product-image-sets resource as a relationship to the concrete-products resource. |
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 list<\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;
}
}
Make sure the following applies:
-
The following 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, theabstract-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, theconcrete-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. |
Spryker\Glue\ProductPricesRestApi\Plugin | |
ConcreteProductPricesRoutePlugin | Registers the concrete-product-prices resource. |
Spryker\Glue\ProductPricesRestApi\Plugin | |
AbstractProductPricesByResourceIdResourceRelationshipPlugin | Adds the abstract-product-prices-resource as a relationship to the abstract-products resource. |
Spryker\Glue\ProductPricesRestApi\Plugin\GlueApplication | |
ConcreteProductPricesByResourceIdResourceRelationshipPlugin | Adds the concrete-product-prices-resource as a relationship to the concrete-products resource. |
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 list<\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;
}
}
Make sure the following applies:
-
The following 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, theabstract-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, theconcrete-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. |
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;
}
}
Send a request to https://glue.mysprykershop.com/abstract-products/{{abstract_sku}}?include=category-nodes
.
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. |
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 list<\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceRoutePluginInterface>
*/
protected function getResourceRoutePlugins(): array
{
return [
new ProductManagementAttributesResourceRoutePlugin(),
];
}
}
Make sure that the following endpoint is available: https://glue.mysprykershop.com/product-management-attributes/{{attribute_key}}
Enable multiselect product attributes
Activate the following plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
MultiSelectAttributeConcreteProductsResourceExpanderPlugin | Formats the “multiselect” attributes of the concrete-products resource to string. |
Spryker\Glue\ProductAttributesRestApi\Plugin\ProductsRestApi | |
MultiSelectAttributeAbstractProductsResourceExpanderPlugin | Formats the “multiselect” attributes of the abstract-products resource to string. |
Spryker\Glue\ProductAttributesRestApi\Plugin\ProductsRestApi |
src/Pyz/Glue/ProductsRestApi/ProductsRestApiDependencyProvider.php
<?php
namespace Pyz\Glue\ProductsRestApi;
use Spryker\Glue\ProductAttributesRestApi\Plugin\ProductsRestApi\MultiSelectAttributeAbstractProductsResourceExpanderPlugin;
use Spryker\Glue\ProductAttributesRestApi\Plugin\ProductsRestApi\MultiSelectAttributeConcreteProductsResourceExpanderPlugin;
use Spryker\Glue\ProductsRestApi\ProductsRestApiDependencyProvider as SprykerProductsRestApiDependencyProvider;
class ProductsRestApiDependencyProvider extends SprykerProductsRestApiDependencyProvider
{
/**
* @return array<\Spryker\Glue\ProductsRestApiExtension\Dependency\Plugin\ConcreteProductsResourceExpanderPluginInterface>
*/
protected function getConcreteProductsResourceExpanderPlugins(): array
{
return [
new MultiSelectAttributeConcreteProductsResourceExpanderPlugin(), // remove if the project is accept product attribute values as array of strings
];
}
/**
* @return array<\Spryker\Glue\ProductsRestApiExtension\Dependency\Plugin\AbstractProductsResourceExpanderPluginInterface>
*/
protected function getAbstractProductsResourceExpanderPlugins(): array
{
return [
new MultiSelectAttributeAbstractProductsResourceExpanderPlugin(), // remove if the project is accept product attribute values as array of strings
];
}
}
Make sure that abstract-products
and concrete-products
resources return “multiselect” product attributes as strings.
Thank you!
For submitting the form