Create storefront resources
Edit on GitHubThis guide shows how to create an API endpoint using a resource for the storefront API application.
Let’s say you have a module named ModuleRestApi
, where you want to have a new endpoint /module
with GET
and POST
methods. To create the endpoint, follow these steps:
- Create
ModuleRestApiConfig
and add the resource name:
\Pyz\Glue\ModuleRestApi\ModuleRestApiConfig
<?php
namespace Pyz\Glue\ModuleRestApi;
use Spryker\Glue\Kernel\AbstractBundleConfig;
class ModuleRestApiConfig extends AbstractBundleConfig
{
public const RESOURCE_MODULE = 'module';
}
- Create
module_api.transfer.xml
:
<?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 that contains information from the request
<transfer name="GlueRequest">
</transfer>
//transfer that contains information about resource
<transfer name="GlueResource">
<property name="type" type="string"/>
<property name="id" type="string"/>
<property name="attributes" type="AbstractAttributes"/>
</transfer>
//transfer that contains information for the response
<transfer name="GlueResponse">
<property name="resources" type="GlueResource[]" singular="resource"/>
</transfer>
//used for collect request body data(if needed)
<transfer name="ModuleRestAttributes">
//add transfer fields
</transfer>
//used for declared list of methods in Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceInterface::getDeclaredMethods()
<transfer name="GlueResourceMethodCollection">
<property name="get" type="GlueResourceMethodConfiguration"/>
<property name="post" type="GlueResourceMethodConfiguration"/>
</transfer>
//used for declared method in Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceInterface::getDeclaredMethods()
<transfer name="GlueResourceMethodConfiguration">
<property name="controller" type="string"/>
<property name="action" type="string"/>
<property name="attributes" type="string"/>
</transfer>
//add other used transfers
</transfers>
- Create
ModuleController
:
\Pyz\Glue\ModuleRestApi\Controller\ModuleController
<?php
namespace Pyz\Glue\ModuleRestApi\Controller;
use Generated\Shared\Transfer\ModuleRestAttributesTransfer;
use Generated\Shared\Transfer\GlueRequestTransfer;
use Generated\Shared\Transfer\GlueResourceTransfer;
use Generated\Shared\Transfer\GlueResponseTransfer;
use Pyz\Glue\ModuleRestApi\ModuleRestApiConfig;
use Spryker\Glue\Kernel\Controller\AbstractStorefrontApiController;
class ModuleResourceController extends AbstractStorefrontApiController
{
public function getAction(
string $id,
GlueRequestTransfer $glueRequestTransfer
): GlueResponseTransfer {
return (new GlueResponseTransfer())
->addResource((new GlueResourceTransfer())
->setId($id)
->setType(ModuleRestApiConfig::RESOURCE_MODULE)
->setAttributes((new ModuleRestAttributesTransfer());
}
public function postAction(
ModuleRestAttributesTransfer $moduleRestAttributesTransfer,
GlueRequestTransfer $glueRequestTransfer
): GlueResponseTransfer {
return (new GlueResponseTransfer())
->addResource((new GlueResourceTransfer())
->setType(ModuleRestApiConfig::RESOURCE_MODULE)
->setAttributes((new ModuleRestAttributesTransfer());
}
}
- Create
ModuleResource
. For no convention resource, it must implementResourceInterface
.
\Pyz\Glue\ModuleRestApi\Plugin\ModuleResource
<?php
namespace Pyz\Glue\ModuleRestApi\Plugin;
use Generated\Shared\Transfer\GlueResourceMethodCollectionTransfer;
use Generated\Shared\Transfer\GlueResourceMethodConfigurationTransfer;
use Generated\Shared\Transfer\ModuleRestAttributesTransfer;
use Pyz\Glue\ModuleRestApi\Controller\ModuleResourceController;
use Spryker\Glue\ModuleRestApi\ModuleRestApiConfig;
use Spryker\Glue\GlueApplication\Plugin\GlueApplication\AbstractResourcePlugin;
use Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceInterface;
class ModuleResource extends AbstractResourcePlugin implements ResourceInterface
{
public function getType(): string
{
return ModuleRestApiConfig::RESOURCE_MODULE;
}
public function getController(): string
{
return ModuleResourceController::class;
}
public function getDeclaredMethods(): GlueResourceMethodCollectionTransfer
{
return (new GlueResourceMethodCollectionTransfer())
->setGet(new GlueResourceMethodConfigurationTransfer())
->setPost(
(new GlueResourceMethodConfigurationTransfer())
->setAction('postAction')->setAttributes(ModuleRestAttributesTransfer::class),
);
}
}
To follow the JSON:API convention, the resource must implement JsonApiResourceInterface
.
\Pyz\Glue\ModuleRestApi\Plugin\JsonConventionModuleResource
<?php
namespace Pyz\Glue\ModuleRestApi\Plugin;
use Generated\Shared\Transfer\GlueResourceMethodCollectionTransfer;
use Generated\Shared\Transfer\GlueResourceMethodConfigurationTransfer;
use Generated\Shared\Transfer\ModuleRestAttributesTransfer;
use Pyz\Glue\ModuleRestApi\Controller\ModuleResourceController;
use Spryker\Glue\ModuleRestApi\ModuleRestApiConfig;
use Spryker\Glue\GlueApplication\Plugin\GlueApplication\AbstractResourcePlugin;
use Spryker\Glue\GlueJsonApiConventionExtension\Dependency\Plugin\ResourceInterface;
class ModuleResource extends AbstractResourcePlugin implements JsonApiResourceInterface
{
public function getType(): string
{
return ModuleRestApiConfig::RESOURCE_MODULE;
}
public function getController(): string
{
return ModuleResourceController::class;
}
public function getDeclaredMethods(): GlueResourceMethodCollectionTransfer
{
return (new GlueResourceMethodCollectionTransfer())
->setGet(new GlueResourceMethodConfigurationTransfer())
->setPost(
(new GlueResourceMethodConfigurationTransfer())
->setAction('postAction')->setAttributes(ModuleRestAttributesTransfer::class),
);
}
}
The default request and response data format are CamelCase, to apply a snake_case naming convention set true
for GlueResourceMethodConfigurationTransfer->setIsSnakeCased()
for each method where you want to change the request and response data format.
See also Create and change Glue API conventions guide.
- Declare the resource:
\Pyz\Glue\GlueStorefrontApiApplication\GlueStorefrontApiApplicationDependencyProvider
<?php
namespace Pyz\Glue\GlueStorefrontApiApplication;
use Pyz\Glue\ModuleRestApi\Plugin\ModuleResource;
use Spryker\Glue\GlueStorefrontApiApplication\GlueStorefrontApiApplicationDependencyProvider as SprykerGlueStorefrontApiApplicationDependencyProvider;
class GlueStorefrontApiApplicationDependencyProvider extends SprykerGlueStorefrontApiApplicationDependencyProvider
{
/**
* @return array<\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\ResourceInterface>
*/
protected function getResourcePlugins(): array
{
return [
new ModuleResource(),
];
}
}
- Build a fresh cache for the API applications controllers.
vendor/bin/glue glue-api:controller:cache:warm-up
If everything is set up correctly, you can access https://glue-storefront.mysprykershop.com/module
.
In Development mode, you do not need to refresh a cache.
- Debug existing routes.
There is a special command to debug all existing routes.
glue route:bebug <applicationType> <options>
The example below shows how to debug Backend routes.
$ docker/sdk/cli
╭─/data | Store: DE | Env: docker.dev | Debug: (.) | Testing: (.)
╰─$ glue route:debug Storefront -c
Code bucket: DE | Store: DE | Environment: docker.dev
------------------- -------- -------- ------ -------- ------------------------------------------------------------------------ --------------
Name Method Scheme Host Path Controller Is Protected
------------------- -------- -------- ------ -------- ------------------------------------------------------------------------ --------------
tokenResourcePost POST ANY ANY /token Spryker\Glue\OauthApi\Controller\TokenResourceController::postAction() No
------------------- -------- -------- ------ -------- ------------------------------------------------------------------------ --------------
Thank you!
For submitting the form