Native API Platform Resources
Edit on GitHubThis document explains how to create API Platform resources using native PHP attributes instead of Spryker’s YAML-based generation pipeline, and how to configure your project to discover these resources.
When to use native resources
Spryker’s YAML schema pipeline (resource.yml files) generates PHP resource classes automatically and provides features like multi-layer merging, validation auto-discovery, and CodeBucket support. For most use cases, the YAML approach is recommended.
Use native API Platform resources when you need features that are not yet supported by the Spryker SchemaParser and ClassGenerator, such as:
- Custom filters (search, date range, order)
- GraphQL support
- Messenger integration
- Custom operations with non-standard HTTP methods
- DTO input/output patterns
- Elasticsearch provider integration
- Any other advanced API Platform feature documented at api-platform.com/docs
Creating a native resource class
A native API Platform resource is a PHP class annotated with #[ApiResource] and related attributes. You can place it in any directory that is configured as a mapping path.
Example resource
<?php
declare(strict_types=1);
namespace Pyz\Glue\Catalog\Api\Backend\Resource;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use Pyz\Glue\Catalog\Api\Backend\Provider\CatalogSearchBackendProvider;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
],
shortName: 'catalog-search',
provider: CatalogSearchBackendProvider::class,
paginationEnabled: true,
paginationItemsPerPage: 20,
)]
final class CatalogSearchBackendResource
{
#[ApiProperty(identifier: true, writable: false)]
public ?string $sku = null;
#[ApiProperty]
public ?string $name = null;
#[ApiProperty]
public ?float $price = null;
#[ApiProperty(writable: false)]
public ?string $url = null;
}
This follows the same provider/processor pattern as generated resources. For full attribute documentation, see the API Platform resource configuration reference.
Provider for the native resource
<?php
declare(strict_types=1);
namespace Pyz\Glue\Catalog\Api\Backend\Provider;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
class CatalogSearchBackendProvider implements ProviderInterface
{
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
// Fetch data from your business layer and return resource objects
}
}
Configuring custom resource paths
API Platform discovers resource classes from directories listed in the mapping.paths configuration. By default, Spryker configures only the generated resource directory:
$apiPlatform->mapping()->paths([
'%kernel.project_dir%/src/Generated/Api/Backend',
]);
To make API Platform discover your native resources, add your directory to this list.
Adding a custom path
Edit the api_platform.php configuration file for the application where your resources should be available.
For GlueBackend resources, edit config/GlueBackend/packages/api_platform.php:
<?php
declare(strict_types=1);
use Symfony\Config\ApiPlatformConfig;
return static function (ApiPlatformConfig $apiPlatform, string $env): void {
$apiPlatform->mapping()->paths([
'%kernel.project_dir%/src/Generated/Api/Backend',
'%kernel.project_dir%/src/Pyz/Glue/*/Api/Backend/Resource',
]);
// ... rest of configuration
};
For GlueStorefront resources, edit config/GlueStorefront/packages/api_platform.php:
$apiPlatform->mapping()->paths([
'%kernel.project_dir%/src/Generated/Api/Storefront',
'%kernel.project_dir%/src/Pyz/Glue/*/Api/Storefront/Resource',
]);
Always keep the src/Generated/Api/{ApiType} path in the list. Removing it disables all YAML-generated resources.
Directory structure example
src/
├── Generated/
│ └── Api/
│ └── Backend/
│ └── CustomersBackendResource.php # Generated from YAML
├── Pyz/
│ └── Glue/
│ └── Catalog/
│ └── Api/
│ └── Backend/
│ ├── Resource/
│ │ └── CatalogSearchBackendResource.php # Native resource
│ └── Provider/
│ └── CatalogSearchBackendProvider.php
Both the generated and native resources are discovered and served by API Platform.
Coexistence with generated resources
Native resources and YAML-generated resources coexist without conflict. API Platform treats all discovered #[ApiResource] classes equally, regardless of whether they were generated or hand-written.
Key points:
- No naming conflicts: Ensure
shortNamevalues are unique across all resources in the same API type. - Same provider/processor pattern: Native resources use the same
ProviderInterfaceandProcessorInterfaceas generated resources. - Same serialization: Native resources use the same JSON:API (or other configured) format.
- Same security model: Native resources can use the same
securityexpressions. See Security.
Limitations of native resources
Native resources bypass the Spryker generation pipeline, which means the following features are not available:
| Feature | Available | Alternative |
|---|---|---|
| Multi-layer schema merging (Core, Feature, Project) | No | Manage inheritance manually |
Validation auto-discovery from .validation.yml |
No | Use #[Assert\*] attributes directly on properties |
| CodeBucket support | No | Use conditional logic in providers |
api:debug command output |
No | Use debug:router instead |
api:generate management |
No | Manage files manually |
Validation on native resources
Without the YAML validation pipeline, add Symfony Validator constraints directly as attributes:
use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource(/* ... */)]
final class CatalogSearchBackendResource
{
#[ApiProperty(identifier: true)]
public ?string $sku = null;
#[Assert\NotBlank]
#[Assert\Length(min: 1, max: 255)]
public ?string $name = null;
#[Assert\PositiveOrZero]
public ?float $price = null;
}
For the full list of available constraints, see the Symfony Validator documentation.
Next steps
- API Platform Configuration - Full configuration reference
- Resource Schemas - YAML-based resource generation
- API Platform official documentation - Full API Platform reference
Thank you!
For submitting the form