Extending a REST API resource

Edit on GitHub

Spryker Glue REST API comes with a set of predefined APIs out of the box. You can extend and customize them to your own project needs by extending the Glue API modules that provide the relevant functionality on your project level.

The following guide relies on your knowledge of the structure of a Glue REST API resource module and the behavior of its constituents. For more details, see the Resource modules section in Glue Infrastructure.

Prerequisites

If you have a development virtual machine with the B2C Demo Shop installed, all the required components are available out of the box.

Assume that you modify the product storage data to match your product requirements—for example, you add the manufacturerCountry field to the product data not as an attribute but as another field in the database.

Now, add this field to responses of the Products API endpoints:

1. Extend Glue transfers

Extend the existing Glue Transfers that describe Glue attributes. Attributes of the products resources are defined in the transfer file products_rest_api.transfer.xml. To extend it, do the following:

  1. Create file src/Pyz/Shared/ProductsRestApi/Transfer/products_rest_api.transfer.xml that extends the transfer on the project level.

All transfer file names end with .transfer.xml.

  1. In the newly created file, define only fields you want to add—in your case, it’s manufacturerCountry:

Code sample

<?xml version="1.0"?>
<transfers xmlns="spryker:transfer-01"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="spryker:transfer-01 http://static.spryker.com/transfer-01.xsd">

    <transfer name="AbstractProductsRestAttributes">
        <property name="manufacturerCountry" type="string"/>
    </transfer>

    <transfer name="ConcreteProductsRestAttributes">
        <property name="manufacturerCountry" type="string"/>
    </transfer>

    </transfers>
  1. Generate transfers:
vendor/bin/console transfer:generate
  1. Check that generated transfers contain the attribute you have added:
  • src/Generated/Shared/Transfer/AbstractProductsRestAttributesTransfer.php—for abstract products.
  • src/Generated/Shared/Transfer/ConcreteProductsRestAttributesTransfer.php—for concrete products.

To extend Glue transfers you also can use a Spryk:

console spryk:run AddSharedRestAttributesTransfer --mode=project --module=ResourcesRestApi --organization=Pyz --name=RestResourcesAttributes

2. Put data

If automatic transfer-to-transfer conversion can be performed, you do not need to take extra steps to put data in the attribute you have added in step 1. Automatic conversion occurs when the attribute name defined in the REST transfer matches exactly the name of the respective field in the storage transfer.

In more complicated cases, to pull data from alternative storage or map data differently from what auto-mapping does, you need to override the processor classes. To add the manufacturerCountry attribute data, override the AbstractProductsResourceMapper class by extending the ProductsRestApi module, which implements the Products API:

  1. Create the src/Pyz/Glue/ProductsRestApi directory.
  2. Implement \Pyz\Glue\ProductsRestApi\Processor\Mapper\AbstractProductsResourceMapper as follows:

AbstractProductsResourceMapper.php

<?php

namespace Pyz\Glue\ProductsRestApi\Processor\Mapper;

use Generated\Shared\Transfer\AbstractProductsRestAttributesTransfer;
use Spryker\Glue\ProductsRestApi\Processor\Mapper\AbstractProductsResourceMapper as SprykerAbstractProductsResourceMapper;

class AbstractProductsResourceMapper extends SprykerAbstractProductsResourceMapper
{
    /**
     * @param array $abstractProductData
     *
     * @return \Generated\Shared\Transfer\AbstractProductsRestAttributesTransfer
     */
    public function mapAbstractProductsDataToAbstractProductsRestAttributes(array $abstractProductData): AbstractProductsRestAttributesTransfer
    {
        $restAbstractProductsAttributesTransfer = parent::mapAbstractProductsDataToAbstractProductsRestAttributes($abstractProductData);

        $restAbstractProductsAttributesTransfer->setManufacturerCountry('Portugal');

        return $restAbstractProductsAttributesTransfer;
    }
}

The implemented mapper extends the original core mapper (located in Spryker\Glue\ProductsRestApi\Processor\Mapper\AbstractProductsResourceMapper) and calls the parent method in the method you override. This lets you avoid redefining the whole class and lets you define only the things you want to override.

To put data, you can also use a Spryk:

console spryk:run AddGlueResourceMapper --mode=project --module=ResourcesRestApi --organization=Pyz  --subDirectory=Mapper --className=Resource

This creates a mapper and adds it to the factory on the project level. You need to extend the mapper from the original feature.

3. Override mapper initialization

Override the initialization of the mapper created in the previous step by extending the factory of the ProductsRestApi module. A factory is used to create objects and processor classes of a module. Thus, by overriding it, you can invoke your new mapper. To do this, follow these steps:

  1. Create the Glue factory on the project level: \Pyz\Glue\ProductsRestApi\ProductsRestApiFactory.
  2. Implement the factory as follows:

ProductsRestApiFactory.php

<?php

namespace Pyz\Glue\ProductsRestApi;

use Pyz\Glue\ProductsRestApi\Processor\Mapper\AbstractProductsResourceMapper;
use Spryker\Glue\ProductsRestApi\Processor\Mapper\AbstractProductsResourceMapperInterface;
use Spryker\Glue\ProductsRestApi\ProductsRestApiFactory as SprykerProductsRestApiFactory;

class ProductsRestApiFactory extends SprykerProductsRestApiFactory
{
    /**
     * @return \Spryker\Glue\ProductsRestApi\Processor\Mapper\AbstractProductsResourceMapperInterface
     */
    public function createAbstractProductsResourceMapper(): AbstractProductsResourceMapperInterface
    {
        return new AbstractProductsResourceMapper();
    }
}

Like the mapper, ProductsRestApiFactory extends the core factory and only overrides the mapper creation.

To override mapper initialization, you can also use a Spryk:

console spryk:run AddGlueMapperFactoryMethod --mode=project --module=ResourcesRestApi --organization=Pyz --subDirectory=Mapper --className=Resource

This adds mapper initialization to the project-level factory.

4. Verify implementation

You can query the Products API to check whether the attribute has been added to the API response. For example, you can query information on one of the products with the manufacturerCountry field populated. For details, see Retrieving abstract products and Retrieving concrete products.