<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Spryker Documentation</title>
        <description>Spryker documentation center.</description>
        <link>https://docs.spryker.com/</link>
        <atom:link href="https://docs.spryker.com/feed.xml" rel="self" type="application/rss+xml"/>
        <lastBuildDate>Thu, 29 Jan 2026 11:35:43 +0000</lastBuildDate>
        <generator>Jekyll v4.2.2</generator>
        
        
        <item>
            <title>API Platform</title>
            <description>&lt;p&gt;Spryker’s API Platform integration provides schema-based API resource generation with automatic OpenAPI documentation. This allows you to define your API resources using YAML schemas and automatically generate fully functional API endpoints with validation, pagination, and serialization.&lt;/p&gt;
&lt;p&gt;This document describes the API Platform architecture and how it integrates with Spryker.&lt;/p&gt;
&lt;h2 id=&quot;what-is-api-platform&quot;&gt;What is API Platform&lt;/h2&gt;
&lt;p&gt;API Platform is a framework for building modern APIs based on web standards and best practices. In Spryker, it complements the existing Glue API infrastructure by providing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Schema-based resource generation&lt;/strong&gt;: Define resources in YAML, generate PHP classes automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic OpenAPI documentation&lt;/strong&gt;: Interactive API documentation generated from schemas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in validation&lt;/strong&gt;: Symfony Validator integration with operation-specific rules&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pagination support&lt;/strong&gt;: Standardized pagination with configurable defaults&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State management&lt;/strong&gt;: Separate providers (read) and processors (write) for clean architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read more about the API Platform project at &lt;a href=&quot;https://api-platform.com/&quot;&gt;api-platform.com&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;CodeBucket support&lt;/div&gt;
&lt;p&gt;Currently, the API-Platform integration does not support code buckets. When defining resources, use only the Core and Project layers.&lt;/p&gt;
&lt;p&gt;Code bucket support is planned for future releases.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;h2 id=&quot;architecture-overview&quot;&gt;Architecture overview&lt;/h2&gt;
&lt;h3 id=&quot;resource-generation-workflow&quot;&gt;Resource generation workflow&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-MARKDOWN&quot;&gt;&gt;Schema Files (YAML)
    ↓
Schema Discovery &amp;amp; Validation
    ↓
Multi-layer Schema Merging (Core → Feature → Project → [Code Buckets])
    ↓
Resource Class Generation
    ↓
API Platform Resource (with attributes)
    ↓
API Endpoints
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;core-components&quot;&gt;Core components&lt;/h3&gt;
&lt;h4 id=&quot;schema-files&quot;&gt;1. Schema files&lt;/h4&gt;
&lt;p&gt;Resources are defined in YAML files located in module directories:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-MARKDOWN&quot;&gt;&gt;src/Spryker/{Module}/resources/api/{api-type}/{resource-name}.resources.yml
src/Spryker/{Module}/resources/api/{api-type}/{resource-name}.validation.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example resource schema &lt;code&gt;src/Spryker/{Module}/resources/api/{api-type}/{resource-name}.resources.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;shortName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;API&quot;&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Pyz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Glue&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Backend&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Provider&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CustomerBackendProvider&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;processor&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Pyz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Glue&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Backend&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Processor&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CustomerBackendProcessor&quot;&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;paginationEnabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Post&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GetCollection&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Patch&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Delete&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;address&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;customerReference&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;writable&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Example validation schema &lt;code&gt;src/Spryker/{Module}/resources/api/{api-type}/{resource-name}.validation.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;NotBlank&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;First name is required&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;64&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;minMessage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;First name must be at least 2 characters&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;maxMessage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;First name cannot exceed 64 characters&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;constraints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;64&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;minMessage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;First name must be at least 2 characters&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;maxMessage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;First name cannot exceed 64 characters&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;generated-resources&quot;&gt;2. Generated resources&lt;/h4&gt;
&lt;p&gt;The generator creates PHP classes with API Platform attributes:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Generated/Api/Backend/CustomersBackendResource.php&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Generated\Api\Backend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\ApiResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\ApiProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Symfony\Component\Validator\Constraints&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#[ApiResource(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;shortName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Customer&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;processor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProcessor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomersBackendResource&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#[ApiProperty(identifier: true, writable: false)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;?string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerReference&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;#[ApiProperty]&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#[Assert\NotBlank(groups: [&apos;customers:create&apos;])]&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#[Assert\Email(groups: [&apos;customers:create&apos;])]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;?string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Getters, setters, toArray(), fromArray()...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;state-providers-and-processors&quot;&gt;3. State providers and processors&lt;/h4&gt;
&lt;p&gt;Detailed information about the API-Platform Provider and Resources can be found on the public docs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://api-platform.com/docs/core/state-providers/&quot;&gt;API Platform Providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api-platform.com/docs/core/state-processors/&quot;&gt;API Platform Processors&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Provider (read operations):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProviderInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Operation&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Fetch and return data from your business layer&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Processor (write operations):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProcessor&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProcessorInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Operation&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Persist changes through your business layer&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$updatedResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;api-types&quot;&gt;API types&lt;/h2&gt;
&lt;p&gt;Any of the &lt;a href=&quot;https://docs.spryker.com/docs/integrations/spryker-glue-api/getting-started-with-apis/getting-started-with-apis&quot;&gt;existing APIs&lt;/a&gt; can be extended using API Platform.&lt;/p&gt;
&lt;p&gt;Spryker supports multiple API types for different use cases:&lt;/p&gt;
&lt;h3 id=&quot;glue-api&quot;&gt;Glue API&lt;/h3&gt;
&lt;p&gt;This API is configured to serve the JSON:API format by default, which can be configured per project. Projects migrating their APIs can provide new APIs as well as supporting the existing ones while migrating.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;storefront&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application:&lt;/strong&gt; Glue&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base URL:&lt;/strong&gt; &lt;code&gt;http://glue.eu.spryker.local/&lt;/code&gt; - Configurable per project&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Customer-facing APIs, mobile apps, PWAs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;gluestorefront-api&quot;&gt;GlueStorefront API&lt;/h3&gt;
&lt;p&gt;Thie API is configured to serve the JSON+LD format by default, which can be configured per project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;storefront&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application:&lt;/strong&gt; Glue&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base URL:&lt;/strong&gt; &lt;code&gt;http://glue-storefront.eu.spryker.local/&lt;/code&gt; - Configurable per project&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Customer-facing APIs, mobile apps, PWAs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;gluebackend-api&quot;&gt;GlueBackend API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;backend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application:&lt;/strong&gt; Zed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base URL:&lt;/strong&gt; &lt;code&gt;http://glue-backend.eu.spryker.local/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Admin panels, internal tools, ERP integrations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;merchant-portal-api&quot;&gt;Merchant Portal API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;merchant-portal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application:&lt;/strong&gt; MerchantPortal&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base URL:&lt;/strong&gt; &lt;code&gt;http://mp.glue.eu.spryker.local/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Marketplace merchant interfaces&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Example:&lt;/strong&gt; &lt;code&gt;/products&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;multi-layer-schema-merging&quot;&gt;Multi-layer schema merging&lt;/h2&gt;
&lt;p&gt;One of the key features is support for multi-layer schema definitions that automatically merge:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Core layer&lt;/strong&gt; (vendor/spryker):&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Feature layer&lt;/strong&gt; (src/SprykerFeature):&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;loyaltyPoints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;integer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Project layer&lt;/strong&gt; (src/Pyz):&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Override core&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;customField&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Project-specific&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: A single merged resource with all properties, project code-bucket layer taking precedence.&lt;/p&gt;
&lt;h2 id=&quot;integration-with-spryker-architecture&quot;&gt;Integration with Spryker architecture&lt;/h2&gt;
&lt;h3 id=&quot;dependency-injection&quot;&gt;Dependency Injection&lt;/h3&gt;
&lt;p&gt;API Platform fully integrates with Symfony Dependency Injection:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// config/Zed/ApplicationServices.php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$services&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Pyz\\Zed\\&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;../../../src/Pyz/Zed/&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Providers and Processors are automatically discovered and can use constructor injection:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackofficeProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProviderInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomerFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerFacade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomerRepositoryInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;facade-integration&quot;&gt;Facade integration&lt;/h3&gt;
&lt;p&gt;Resources can leverage existing Spryker facades:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProcessor&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProcessorInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomerFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerFacade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Operation&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapToTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customerFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;createCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapToResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCustomerTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;resource-generation&quot;&gt;Resource generation&lt;/h2&gt;
&lt;h3 id=&quot;console-commands&quot;&gt;Console commands&lt;/h3&gt;
&lt;p&gt;All the following commands can be used with a specific GLUE_APPLICATION by prefixing them with &lt;code&gt;GLUE_APPLICATION=GLUE_BACKEND&lt;/code&gt; environment variable. For example: &lt;code&gt;docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:debug --list&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Generate resource classes for all configured API types at once. Usually used during deployment/installation.&lt;/span&gt;
docker/sdk cli glue api:generate

&lt;span class=&quot;c&quot;&gt;# Generate API type specific resource classes. Usually used during development.&lt;/span&gt;
docker/sdk cli glue api:generate backend

&lt;span class=&quot;c&quot;&gt;# Validate schemas only to see if there is any issue in the definitions&lt;/span&gt;
docker/sdk cli glue api:generate &lt;span class=&quot;nt&quot;&gt;--validate-only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;debug-commands&quot;&gt;Debug commands&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# List all resources to see which ones are defined in the schema files.&lt;/span&gt;
docker/sdk cli glue  api:debug &lt;span class=&quot;nt&quot;&gt;--list&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Inspect specific resource and print details about properties and operations&lt;/span&gt;
docker/sdk cli glue  api:debug customers &lt;span class=&quot;nt&quot;&gt;--api-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;backend

&lt;span class=&quot;c&quot;&gt;# Show merged schema&lt;/span&gt;
docker/sdk cli glue  api:debug customers &lt;span class=&quot;nt&quot;&gt;--api-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;backend &lt;span class=&quot;nt&quot;&gt;--show-merged&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Show contributing files for a resource&lt;/span&gt;
docker/sdk cli glue  api:debug customers &lt;span class=&quot;nt&quot;&gt;--api-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;backend &lt;span class=&quot;nt&quot;&gt;--show-sources&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;/h2&gt;
&lt;h3 id=&quot;automatic-openapi-documentation&quot;&gt;Automatic OpenAPI documentation&lt;/h3&gt;
&lt;p&gt;API Platform generates interactive OpenAPI documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Swagger UI at the root URL &lt;code&gt;/&lt;/code&gt; for example &lt;code&gt;http://glue-backend.eu.spryker.local/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can disable this interface in production environments by configuring the settings in your &lt;code&gt;api_platform.php&lt;/code&gt; configuration file. For details, see &lt;a href=&quot;/docs/dg/dev/architecture/api-platform/configuration.html#disable-swaggerui-in-production&quot;&gt;Disable Swagger UI&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;built-in-validation&quot;&gt;Built-in validation&lt;/h3&gt;
&lt;p&gt;Validation rules from &lt;code&gt;*.validation.yml&lt;/code&gt; files are converted to Symfony Validator constraints:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;NotBlank&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Becomes:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#[Assert\NotBlank(groups: [&apos;customers:create&apos;])]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#[Assert\Email(groups: [&apos;customers:create&apos;])]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;?string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;pagination-support&quot;&gt;Pagination support&lt;/h3&gt;
&lt;p&gt;Standardized pagination with query parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-MARKDOWN&quot;&gt;&gt;GET /customers?page=2&amp;amp;itemsPerPage=20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Provider returns &lt;code&gt;PaginatorInterface&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TraversablePaginator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ArrayObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$currentPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$itemsPerPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$totalItems&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;operation-specific-behavior&quot;&gt;Operation-specific behavior&lt;/h3&gt;
&lt;p&gt;Define different validation and behavior per operation:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Post&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# Create&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;# Read one&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GetCollection&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Read many&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Patch&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;# Update&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Delete&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;# Delete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Each operation can have specific validation rules and security settings.&lt;/p&gt;
&lt;h2 id=&quot;performance&quot;&gt;Performance&lt;/h2&gt;
&lt;h3 id=&quot;cache-warming&quot;&gt;Cache warming&lt;/h3&gt;
&lt;p&gt;Pre-generate resources during deployment:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk cli glue  api:generate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk cli glue  cache:warmup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;property-level-access-control&quot;&gt;Property-level access control&lt;/h3&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;writable&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Can be written&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;readable&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Not in responses&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;comparison-with-glue-api&quot;&gt;Comparison with Glue API&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;API Platform&lt;/th&gt;
&lt;th&gt;Glue API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Definition&lt;/td&gt;
&lt;td&gt;Schema-based (YAML)&lt;/td&gt;
&lt;td&gt;Code-based (PHP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Auto-generated OpenAPI&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;Declarative&lt;/td&gt;
&lt;td&gt;Programmatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standards&lt;/td&gt;
&lt;td&gt;JSON-LD, Hydra&lt;/td&gt;
&lt;td&gt;JSON API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning curve&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use cases&lt;/td&gt;
&lt;td&gt;Standard CRUD&lt;/td&gt;
&lt;td&gt;Complex business logic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both can coexist in the same application. For further migration guidance, see &lt;a href=&quot;/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform.html&quot;&gt;How to migrate to API Platform&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;related-documentation&quot;&gt;Related documentation&lt;/h2&gt;
&lt;p&gt;For detailed implementation guides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/upgrade-and-migrate/integrate-api-platform.html&quot;&gt;How to integrate API Platform&lt;/a&gt; - Setup and configuration&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform.html&quot;&gt;How to migrate to API Platform&lt;/a&gt; - Migrate endpoints from Glue API&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/configuration.html&quot;&gt;API Platform Configuration&lt;/a&gt; - Configure API Platform settings&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/enablement.html&quot;&gt;API Platform Enablement&lt;/a&gt; - Creating your first resource&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/resource-schemas.html&quot;&gt;Resource Schemas&lt;/a&gt; - Resource Schemas&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/validation-schemas.html&quot;&gt;Validation Schemas&lt;/a&gt; - Validation Schemas&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/code-buckets.html&quot;&gt;CodeBucket Support&lt;/a&gt; - Region-specific resources&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/troubleshooting.html&quot;&gt;Troubleshooting API Platform&lt;/a&gt; - Common issues&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/upgrade-and-migrate/integrate-api-platform.html&quot;&gt;How to integrate API Platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/code-buckets.html&quot;&gt;CodeBucket Support in API Platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api-platform.com/docs/&quot;&gt;API Platform official documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
            <pubDate>Thu, 29 Jan 2026 11:34:53 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/api-platform.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/api-platform.html</guid>
            
            
        </item>
        
        <item>
            <title>API Platform Configuration</title>
            <description>&lt;p&gt;Spryker uses &lt;a href=&quot;https://api-platform.com/docs/core/configuration/#symfony-configuration&quot;&gt;API Platform’s configuration options&lt;/a&gt; with Spryker-specific adaptations for PHP-based configuration and environment control.&lt;/p&gt;
&lt;h2 id=&quot;configuration-file-locations&quot;&gt;Configuration file locations&lt;/h2&gt;
&lt;p&gt;Configuration files are located in application-specific directories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GlueBackend:&lt;/strong&gt; &lt;code&gt;config/GlueBackend/packages/api_platform.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GlueStorefront:&lt;/strong&gt; &lt;code&gt;config/GlueStorefront/packages/api_platform.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Glue:&lt;/strong&gt; &lt;code&gt;config/Glue/packages/api_platform.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;spryker-specific-differences&quot;&gt;Spryker-specific differences&lt;/h2&gt;
&lt;h3 id=&quot;php-configuration-instead-of-yaml&quot;&gt;PHP configuration instead of YAML&lt;/h3&gt;
&lt;p&gt;Spryker uses PHP configuration with Symfony’s type-safe configuration objects instead of YAML files:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Symfony\Config\ApiPlatformConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ApiPlatformConfig&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Configuration here&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;environment-variable-for-conditional-settings&quot;&gt;Environment variable for conditional settings&lt;/h3&gt;
&lt;p&gt;The configuration function receives an &lt;code&gt;$env&lt;/code&gt; parameter for environment-specific behavior:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ApiPlatformConfig&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Enable developer tools only in development&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;dockerdev&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableSwagger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableSwaggerUi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableReDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableDocs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Common environment values: &lt;code&gt;prod&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;dockerdev&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;configuration-examples&quot;&gt;Configuration examples&lt;/h2&gt;
&lt;h3 id=&quot;disable-swaggerui-in-production&quot;&gt;Disable SwaggerUI in production&lt;/h3&gt;
&lt;p&gt;Spryker shows the SwaggerUI only in development environments by default. This can be configured with:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;dockerdev&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableSwagger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableSwaggerUi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableReDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enableDocs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;disable-doctrine-integration&quot;&gt;Disable Doctrine integration&lt;/h3&gt;
&lt;p&gt;Spryker does not use Doctrine with API Platform:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;doctrine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;doctrineMongodbOdm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;configure-resource-mapping-paths&quot;&gt;Configure resource mapping paths&lt;/h3&gt;
&lt;p&gt;Specify where generated API resources are located:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;%kernel.project_dir%/src/Generated/Api/Backend&apos;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;set-pagination-defaults&quot;&gt;Set pagination defaults&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;paginationItemsPerPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pagination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pageParameterName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;page&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;itemsPerPageParameterName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;itemsPerPage&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;configure-supported-formats&quot;&gt;Configure supported formats&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;formats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;jsonapi&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;mime_types&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;application/vnd.api+json&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;formats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;jsonld&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;mime_types&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;application/ld+json&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$apiPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;formats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;xml&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;mime_types&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;application/xml&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;complete-configuration-reference&quot;&gt;Complete configuration reference&lt;/h2&gt;
&lt;p&gt;For all available configuration options and their details, refer to the &lt;a href=&quot;https://api-platform.com/docs/core/configuration/#symfony-configuration&quot;&gt;API Platform Symfony Configuration documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The PHP method names in &lt;code&gt;ApiPlatformConfig&lt;/code&gt; correspond directly to the YAML keys in the official documentation.&lt;/p&gt;
</description>
            <pubDate>Thu, 29 Jan 2026 11:19:00 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/api-platform/configuration.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/api-platform/configuration.html</guid>
            
            
        </item>
        
        <item>
            <title>How to integrate API Platform</title>
            <description>This document describes how to integrate API Platform into your Spryker application to enable schema-based API resource generation.

## Prerequisites

Before integrating API Platform, ensure you have:

- Upgraded to Symfony Dependency Injection as described in [How to upgrade to Symfony Dependency Injection](/docs/dg/dev/upgrade-and-migrate/upgrade-to-symfony-dependency-injection.html)
- PHP 8.1 or higher
- Symfony 6.4 or higher components

## 1. Install the required modules

To integrate API Platform, install the following modules:

```bash
composer require spryker/api-platform:&quot;^0.5.0&quot; --update-with-dependencies
```

{% info_block infoBox &quot;Module placeholder&quot; %}

The exact module versions will be provided in the final documentation. The above serves as a placeholder for the module list.

{% endinfo_block %}

## 2. Register bundles

Register the required bundles in your application&apos;s bundle configuration files for each application layer where you want to enable API Platform.

### For Glue application

`config/Glue/bundles.php`

```php
&lt;?php

declare(strict_types = 1);

use ApiPlatform\Symfony\Bundle\ApiPlatformBundle;
use Spryker\ApiPlatform\SprykerApiPlatformBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;

return [
    FrameworkBundle::class =&gt; [&apos;all&apos; =&gt; true],
    TwigBundle::class =&gt; [&apos;all&apos; =&gt; true],
    ApiPlatformBundle::class =&gt; [&apos;all&apos; =&gt; true],
    SprykerApiPlatformBundle::class =&gt; [&apos;all&apos; =&gt; true],
];
```

### For GlueStorefront application

`config/GlueStorefront/bundles.php`

```php
&lt;?php

declare(strict_types = 1);

use ApiPlatform\Symfony\Bundle\ApiPlatformBundle;
use Spryker\ApiPlatform\SprykerApiPlatformBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;

return [
    FrameworkBundle::class =&gt; [&apos;all&apos; =&gt; true],
    ApiPlatformBundle::class =&gt; [&apos;all&apos; =&gt; true],
    SprykerApiPlatformBundle::class =&gt; [&apos;all&apos; =&gt; true],
    TwigBundle::class =&gt; [&apos;all&apos; =&gt; true],
];
```

### For GlueBackend application

`config/GlueBackend/bundles.php`

```php
&lt;?php

declare(strict_types = 1);

use ApiPlatform\Symfony\Bundle\ApiPlatformBundle;
use Spryker\ApiPlatform\SprykerApiPlatformBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;

return [
    FrameworkBundle::class =&gt; [&apos;all&apos; =&gt; true],
    ApiPlatformBundle::class =&gt; [&apos;all&apos; =&gt; true],
    SprykerApiPlatformBundle::class =&gt; [&apos;all&apos; =&gt; true],
    TwigBundle::class =&gt; [&apos;all&apos; =&gt; true],
];
```

## 3. Configure API Platform

Create configuration files for the API Platform in each application layer where you want to enable the API-Platform.

### Configure for Glue

`config/Glue/packages/spryker_api_platform.php`

```php
&lt;?php

declare(strict_types=1);

use Symfony\Config\SprykerApiPlatformConfig;

return static function (SprykerApiPlatformConfig $sprykerApiPlatform): void {
    $sprykerApiPlatform-&gt;apiTypes([&apos;storefront&apos;]);
};
```

### Configure for GlueStorefront

`config/GlueStorefront/packages/spryker_api_platform.php`

```php
&lt;?php

declare(strict_types=1);

use Symfony\Config\SprykerApiPlatformConfig;

return static function (SprykerApiPlatformConfig $sprykerApiPlatform): void {
    $sprykerApiPlatform-&gt;apiTypes([&apos;storefront&apos;]);
};
```

### Configure for GlueBackend

`config/GlueBackend/packages/spryker_api_platform.php`

```php
&lt;?php

declare(strict_types=1);

use Symfony\Config\SprykerApiPlatformConfig;

return static function (SprykerApiPlatformConfig $sprykerApiPlatform): void {
    $sprykerApiPlatform-&gt;apiTypes([&apos;backend&apos;]);
};
```

## 4. Update Router Configuration

Update the router dependency provider for each application where you want to enable API Platform routes.

### For Glue application

`src/Pyz/Glue/Router/RouterDependencyProvider.php`

```php
&lt;?php

declare(strict_types = 1);

namespace Pyz\Glue\Router;

use Spryker\Glue\Router\Plugin\Router\SymfonyFrameworkRouterPlugin;
use Spryker\Glue\GlueApplication\Plugin\Rest\GlueRouterPlugin;
use Spryker\Glue\Router\RouterDependencyProvider as SprykerRouterDependencyProvider;

class RouterDependencyProvider extends SprykerRouterDependencyProvider
{
    /**
     * @return array&lt;\Spryker\Glue\RouterExtension\Dependency\Plugin\RouterPluginInterface&gt;
     */
    protected function getRouterPlugins(): array
    {
        return [
            new GlueRouterPlugin(), // Existing Glue API router
            new SymfonyFrameworkRouterPlugin(), // Add this for API Platform routes
        ];
    }
}
```

{% info_block infoBox &quot;Router order matters&quot; %}

The order of router plugins matters. The `SymfonyFrameworkRouterPlugin` must be added after existing router plugins to ensure the correct routing priority. The `GlueRouterPlugin` should remain the first in the list to handle existing and not yet migrated Glue API endpoints.

When migrating existing Glue API endpoints to API Platform, you need to remove endpoints from the `GlueRouterPlugin` so that the `SymfonyFrameworkRouterPlugin` is used to resolve the route. To remove routes from the `GlueRouterPlugin` update the corresponding `GlueApplicationDependencyProvider`, `GlueBackendApiApplicationDependencyProvider`, or `GlueStorefrontApiApplicationDependencyProvider` and remove the resource route plugin for the route you currently migrate.

{% endinfo_block %}

## 5. Generate API resources

After configuration, generate your API resources from schema files:

```bash
# Generate resources for all configured API types in Glue
docker/sdk cli glue api:generate

# Generate resources for all configured API types in GlueStorefront
docker/sdk cli GLUE_APPLICATION=GLUE_STOREFRONT glue api:generate

# Generate resources for all configured API types in GlueBackend
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate

# Generate resources for a specific API type in Glue (others can follow the env var examples above)
docker/sdk cli glue api:generate storefront
docker/sdk cli glue api:generate backend

# Dry run (see what would be generated)
docker/sdk cli glue api:generate --dry-run

# Validate schemas only
docker/sdk cli glue api:generate --validate-only
```

The generated resources will be created in `src/Generated/Api/{ApiType}/` directory.

## 6. Install assets for the API Platform documentation interface

Install the necessary assets for API Platform to function correctly:

### For Glue application

```bash
docker/sdk cli glue assets:install public/Glue/assets --symlink
```

### For GlueStorefront

```bash
docker/sdk cli GLUE_APPLICATION=GLUE_STOREFRONT glue assets:install public/GlueStorefront/assets/ --symlink
```

### For GlueBackend

```bash
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue assets:install public/GlueBackend/assets/ --symlink
```

{% info_block warningBox &quot;Required step&quot; %}

The `assets:install` command is required to copy the necessary assets (CSS, JavaScript, images) for the API Platform documentation interface. Without this step, the API documentation UI will not display correctly.

{% endinfo_block %}

## 7. Clear caches

After generation and asset installation, clear application caches:

```bash
# Clear all caches
console cache:clear

# Build Symfony container cache
console container:build
```

## Verification

To verify your integration:

1. **Debug available resources:**

   ```bash
   # List all API resources
   docker/sdk cli glue  api:debug --list

   # Inspect specific resource
   docker/sdk cli glue  api:debug access-tokens --api-type=storefront
   ```

2. **Access API documentation:**
   - Glue: `https://glue.your-domain/`
   - GlueStorefront: `https://glue-storefront.your-domain/`
   - GlueBackend: `https://glue-backend.your-domain/`

   The interactive OpenAPI documentation interface will be displayed at the root URL of each application.

   Depending on the environment of the application (development or production), the documentation interface may be enabled or disabled by default. Currently, it is only enabled in development (docker.dev) environments.
   
   You can enable/disable this interface by configuring the settings in your `api_platform.php` configuration files.

## Next steps

- [API Platform](/docs/dg/dev/architecture/api-platform.html) - Overview and concepts
- [Enablement](/docs/dg/dev/architecture/api-platform/enablement.html) - Create your first API resource
- [Resource Schemas](/docs/dg/dev/architecture/api-platform/resource-schemas.html) - Resource Schemas
- [Validation Schemas](/docs/dg/dev/architecture/api-platform/validation-schemas.html) - Validation Schemas
</description>
            <pubDate>Thu, 29 Jan 2026 10:05:27 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/upgrade-and-migrate/integrate-api-platform.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/upgrade-and-migrate/integrate-api-platform.html</guid>
            
            
        </item>
        
        <item>
            <title>Enable Google Material Icons in Back Office</title>
            <description>&lt;p&gt;This guide explains how to enable &lt;strong&gt;Google Material Icons&lt;/strong&gt; in the Spryker Cloud Commerce OS Back Office.&lt;br /&gt;
By enabling these icons, you can modernize your admin interface and improve its overall appearance.&lt;/p&gt;
&lt;p&gt;To display a Material Icon in your templates, use the following HTML markup:&lt;/p&gt;
&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;material-symbols-outlined&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;search&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;material-symbols-outlined&lt;/code&gt; — defines the Material Icon style.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;search&lt;/code&gt; — defines the name of the icon to render.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can explore all available icons on the &lt;a href=&quot;https://fonts.google.com/icons&quot;&gt;Google Material Icons website&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;steps-to-enable-material-ui-icons&quot;&gt;Steps to Enable Material UI Icons&lt;/h2&gt;
&lt;h3 id=&quot;update-the-required-module&quot;&gt;1. Update the Required Module&lt;/h3&gt;
&lt;p&gt;Update the &lt;code&gt;spryker/gui&lt;/code&gt; module to version 4.8.0 or higher:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;composer update spryker/gui:&lt;span class=&quot;s2&quot;&gt;&quot;^4.8.0&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;configure-the-default-icon-type&quot;&gt;2. Configure the Default Icon Type&lt;/h3&gt;
&lt;p&gt;Create or update the &lt;code&gt;GuiConfig&lt;/code&gt; class on the project level to set the default icon type to &lt;code&gt;google-material&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;src/Pyz/Zed/Gui/GuiConfig.php&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strict_types&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\Gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\Gui\GuiConfig&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerGuiConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GuiConfig&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerGuiConfig&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAVIGATION_ICONS_TYPE_DEFAULT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;google-material&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Available options:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&apos;font-awesome&apos;&lt;/code&gt; — the classic icon set (default)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&apos;google-material&apos;&lt;/code&gt; — the new Material UI icons&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;register-the-twig-plugin&quot;&gt;3. Register the Twig Plugin&lt;/h3&gt;
&lt;p&gt;Register the &lt;code&gt;NavigationIconsTypeTwigPlugin&lt;/code&gt; to make the icon type available in Twig templates:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;src/Pyz/Zed/Twig/TwigDependencyProvider.php&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strict_types&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\Twig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\Gui\Communication\Plugin\Twig\NavigationIconsTypeTwigPlugin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\Twig\TwigDependencyProvider&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerTwigDependencyProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TwigDependencyProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerTwigDependencyProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/**
     * @return array&amp;lt;\Spryker\Shared\TwigExtension\Dependency\Plugin\TwigPluginInterface&amp;gt;
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getTwigPlugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// ...existing plugins...&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NavigationIconsTypeTwigPlugin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;configure-icons-in-the-navigation&quot;&gt;4. Configure Icons in the Navigation&lt;/h3&gt;
&lt;p&gt;To use Material Icons in the Back Office sidebar navigation, update the &lt;code&gt;config/Zed/navigation.xml&lt;/code&gt; file.&lt;br /&gt;
Add or modify the &lt;code&gt;&amp;lt;icon&amp;gt;&lt;/code&gt; elements for each navigation item with the desired Material Icon name.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;config&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;dashboard&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Dashboard&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Dashboard&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;bundle&amp;gt;&lt;/span&gt;dashboard&lt;span class=&quot;nt&quot;&gt;&amp;lt;/bundle&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;controller&amp;gt;&lt;/span&gt;index&lt;span class=&quot;nt&quot;&gt;&amp;lt;/controller&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;action&amp;gt;&lt;/span&gt;index&lt;span class=&quot;nt&quot;&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;icon&amp;gt;&lt;/span&gt;grid_view&lt;span class=&quot;nt&quot;&gt;&amp;lt;/icon&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dashboard&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;sales&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Sales&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;uri&amp;gt;&lt;/span&gt;/sales&lt;span class=&quot;nt&quot;&gt;&amp;lt;/uri&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Sales&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;icon&amp;gt;&lt;/span&gt;local_mall&lt;span class=&quot;nt&quot;&gt;&amp;lt;/icon&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;pages&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;order-list&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Orders&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Orders&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;bundle&amp;gt;&lt;/span&gt;sales&lt;span class=&quot;nt&quot;&gt;&amp;lt;/bundle&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;controller&amp;gt;&lt;/span&gt;index&lt;span class=&quot;nt&quot;&gt;&amp;lt;/controller&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;action&amp;gt;&lt;/span&gt;index&lt;span class=&quot;nt&quot;&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/order-list&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/pages&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/sales&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/config&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;section class=&apos;info-block &apos;&gt;&lt;i class=&apos;info-block__icon icon-info&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Tip&lt;/div&gt;
You can browse available icon names at [fonts.google.com/icons](https://fonts.google.com/icons).  
For suggested icons, see the example configuration in the [Spryker B2B Demo Marketplace repository](https://github.com/spryker-shop/b2b-demo-marketplace/blob/master/config/Zed/navigation.xml).
&lt;/div&gt;&lt;/section&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;rebuild-the-navigation-cache&quot;&gt;5. Rebuild the Navigation Cache&lt;/h3&gt;
&lt;p&gt;After updating your navigation configuration, rebuild the navigation cache with the following command:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk console navigation:build-cache
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;result&quot;&gt;Result&lt;/h2&gt;
&lt;p&gt;After you complete these steps, the Spryker Back Office displays &lt;strong&gt;Google Material Icons&lt;/strong&gt; throughout the sidebar navigation, resulting in a clean, modern, and professional appearance.&lt;/p&gt;
</description>
            <pubDate>Wed, 28 Jan 2026 09:55:40 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/back-office/latest/base-shop/install-and-upgrade/enable-google-material-icons.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/back-office/latest/base-shop/install-and-upgrade/enable-google-material-icons.html</guid>
            
            
        </item>
        
        <item>
            <title>Troubleshooting Dependency Injection</title>
            <description>This document describes common issues and solutions when working with Symfony&apos;s Dependency Injection component in Spryker.

## Container compilation failures

### Unknown classes from core

**Problem:**

The container compilation fails with an error about an unknown class from a Spryker core module.

**Example error:**

```php
The service &quot;Spryker\Zed\Product\Business\ProductFacade&quot; has a dependency on a non-existent service &quot;Spryker\Zed\Product\Business\SomeInternalService&quot;.
```

**Cause:**

You&apos;re trying to autowire a class from a core module that doesn&apos;t have a pre-compiled container or isn&apos;t configured in your `ApplicationServices.php`.

**Solution 1 - Register the service manually:**

Add the missing service to your `config/Zed/ApplicationServices.php`:

```php
&lt;?php

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Spryker\Zed\Product\Business\ProductFacadeInterface;
use Spryker\Zed\Product\Business\ProductFacade;

return static function (ContainerConfigurator $configurator): void {
    $services = $configurator-&gt;services()
        -&gt;defaults()
        -&gt;autowire()
        -&gt;public()
        -&gt;autoconfigure();

    // Register the missing core service
    $services-&gt;set(ProductFacadeInterface::class, ProductFacade::class);
};
```

**Solution 2 - Create a project-level extension:**

Create your own class that extends the core service and register it:

```php
&lt;?php

namespace Pyz\Zed\Product\Business;

use Spryker\Zed\Product\Business\ProductFacade as SprykerProductFacade;

class ProductFacade extends SprykerProductFacade
{
}
```

Then ensure it&apos;s auto-discovered through your `ApplicationServices.php` service discovery.

### Missing core module container

**Problem:**

Core module doesn&apos;t have a pre-compiled container, and autowiring fails.

**Example error:**

```php
Could not find the &quot;Spryker\Zed\Customer\Business\CustomerFacade&quot; in any of the attached containers.
```

**Cause:**

The core module hasn&apos;t been updated to support DI compilation yet.

**Solution:**

Create a project-level extension of the service and configure its dependencies manually:

```php
&lt;?php

namespace Pyz\Zed\Customer\Business;

use Spryker\Zed\Customer\Business\CustomerFacade as SprykerCustomerFacade;

class CustomerFacade extends SprykerCustomerFacade
{
    // Your project extensions if needed
}
```

Then register it in `ApplicationServices.php`:

```php
$services-&gt;set(CustomerFacadeInterface::class, \Pyz\Zed\Customer\Business\CustomerFacade::class);
```

### Scalar constructor arguments

**Problem:**

Container compilation fails when a service constructor has scalar type hints (int, string, bool, float).

**Example error:**

```php
Cannot autowire service &quot;Pyz\Zed\MyModule\MyService&quot;: argument &quot;$timeout&quot; of method &quot;__construct()&quot; is type-hinted &quot;int&quot;, you should configure its value explicitly.
```

**Cause:**

Autowiring cannot determine what value to inject for scalar types. The container needs explicit configuration.

**Solution 1 - Configure the argument explicitly:**

```php
&lt;?php

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Pyz\Zed\MyModule\MyService;

return static function (ContainerConfigurator $configurator): void {
    $services = $configurator-&gt;services()
        -&gt;defaults()
        -&gt;autowire()
        -&gt;public()
        -&gt;autoconfigure();

    $services-&gt;set(MyService::class)
        -&gt;arg(&apos;$timeout&apos;, 30);
};
```

**Solution 2 - Use a configuration object (recommended):**

Instead of scalar arguments, create a value object:

```php
&lt;?php

namespace Pyz\Zed\MyModule;

class MyServiceConfig
{
    public function __construct(
        public readonly int $timeout = 30
    ) {
    }
}

class MyService
{
    public function __construct(
        private MyServiceConfig $config
    ) {
    }
}
```


### Transfer objects in properties or constants

**Problem:**

Container compilation fails when transfer objects are used in class properties or constants.

**Example error:**

```php
Class &quot;Generated\Shared\Transfer\CustomerTransfer&quot; not found.
```

**Cause:**

Transfer objects are generated at runtime. During container compilation (especially on fresh installations), transfer objects don&apos;t exist yet.

**Solution 1 - Use transfer objects only in methods:**

```php
&lt;?php

namespace Pyz\Zed\Customer\Business;

class CustomerProcessor
{
    // ❌ WRONG - Will fail during compilation
    private const DEFAULT_CUSTOMER = CustomerTransfer::class;
    private CustomerTransfer $defaultCustomer;

    // ✅ CORRECT - Transfer objects only in method signatures
    public function process(CustomerTransfer $customer): CustomerTransfer
    {
        // Use transfer objects here
        return $customer;
    }
}
```

**Solution 2 - Exclude modules during compilation:**

In `ApplicationServices.php`, exclude modules that heavily use transfers:

```php
&lt;?php

$excludedModuleConfiguration = [
    &apos;DataImport&apos; =&gt; true, // Often uses many transfer objects
    &apos;ProductPageSearch&apos; =&gt; true,
    &apos;ProductStorage&apos; =&gt; true,
];

foreach ($projectModules as $moduleTransfer) {
    if (isset($excludedModuleConfiguration[$moduleTransfer-&gt;getName()])) {
        continue; // Skip this module
    }

    // ... load module services
}
```

### Argument is type-hinted &quot;array&quot;

**Problem:**

The container compilation fails with an error about configuring values explicitly.

**Example error:**

```php
Cannot autowire service &quot;Spryker\Glue\AuthRestApi\Processor\AccessTokens\AccessTokenUserFinder&quot;: argument &quot;$restUserExpanderPlugins&quot; of method &quot;__construct()&quot; is type-hinted &quot;array&quot;, you should configure its value explicitly.
```

**Cause:**

Symfony can&apos;t automatically detect which classes it should inject as dependency for array&apos;s. There is a type-hint to an array of interfaces but which ones should be added here can&apos;t be automatically detected.

**Solution - Use the Stack Attribute:**

```php
&lt;?php

namespace Spryker\Glue\AuthRestApi\Processor\AccessTokens;

use Spryker\Service\Container\Attributes\Stack;

class AccessTokenUserFinder implements AccessTokenUserFinderInterface
{
    /**
     * @param array&lt;\Spryker\Glue\AuthRestApiExtension\Dependency\Plugin\RestUserMapperPluginInterface&gt; $restUserExpanderPlugins
     */
    #[Stack(
        dependencyProvider: AuthRestApiDependencyProvider::class,
        dependencyProviderMethod: &apos;getRestUserExpanderPlugins&apos;,
        provideToArgument: &apos;$restUserExpanderPlugins&apos;,
    )]
    public function __construct(
        protected array $restUserExpanderPlugins
    ) {}
}
```

During compilation the `\Spryker\Service\Container\Pass\StackResolverPass` understands this configuration and will inject the array dependency through this configuration. When the class is requested from the container, the container knows that it has to pass the returned array from the `AuthRestApiDependencyProvider::getRestUserExpanderPlugins()` method to the argument `$restUserExpanderPlugins`.

Multiple Stack attributes can be used on a class constructor.

## Debugging

When you need to understand how the container resolves services or troubleshoot issues, debug into these key classes:

### ContainerDelegator - Service resolution

**Location:** `Spryker\Service\Container\ContainerDelegator`

**Purpose:** Tracks which service from which container gets resolved.

**Key methods to debug:**

- `get(string $id)`: Main entry point for service resolution (line 94)
- `findInProjectContainer(string $id)`: Searches for services in project container (line 226)
- `getPartsFromId(string $id)`: Extracts namespace, application, module from service ID (line 430)

**What to look for:**

- Check `$this-&gt;resolvedServices` to see already resolved services
- Inspect `$this-&gt;containers` to see attached containers (project_container, application_container)
- Review `$this-&gt;checkedContainer` for which containers were searched

**Debug example:**

```php
// Add breakpoint in ContainerDelegator::get()
public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE): ?object
{
    // Check here what $id is being requested
    // Inspect $this-&gt;containers to see available containers
    // Step through to see resolution logic
}
```

### ControllerResolver - Controller discovery

**Location:** `Spryker\Shared\Router\Resolver\ControllerResolver`

**Purpose:** Resolves controller classes from route definitions and injects dependencies.

**Key methods to debug:**

- `getController(Request $request)`: Main entry point for controller resolution (line 37)
- `getControllerFromString()`: Handles string-based controller definitions (line 66)
- `injectContainerAndInitialize()`: Injects dependencies into controller (line 170)

**What to look for:**

- Check how the controller string is parsed
- See if controller is found in ContainerDelegator via `$globalContainer-&gt;has($controller)` (line 75)
- Verify if controller is being instantiated via DI or traditionally

**Debug example:**

```php
// Add breakpoint in ControllerResolver::getController()
public function getController(Request $request): callable|false
{
    $controller = $request-&gt;attributes-&gt;get(&apos;_controller&apos;);
    // Check $controller value
    // Step through to see if it&apos;s resolved from container
}
```

### Kernel - Application setup

**Location:** `Spryker\Shared\Application\Kernel`

**Purpose:** Sets up the application, manages ApplicationPlugins, and boots the container.

**Extends:** `Symfony\Component\HttpKernel\Kernel`

**Uses:** `Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait`

**Key methods to debug:**

- `__construct()`: Initial setup, attaches containers to ContainerDelegator (line 44)
- `boot()`: Boots Symfony container and ApplicationPlugins (line 130)
- `build()`: Registers compiler passes (line 248)
- `configureContainer()`: Loads service configuration files (line 209)

**Important Symfony base class methods:**

Refer to Symfony documentation for these methods:

- [Symfony HttpKernel Component](https://symfony.com/doc/current/components/http_kernel.html)
- [MicroKernelTrait](https://symfony.com/doc/current/configuration/micro_kernel_trait.html)

**What to look for:**

- Check which ApplicationPlugins are registered
- Inspect `$this-&gt;container` to see if it&apos;s ContainerDelegator or Symfony container
- Review which compiler passes are added
- Verify service configuration file loading

**Debug example:**

```php
// Add breakpoint in Kernel::boot()
public function boot(): void
{
    // Check if container is already compiled
    // See which ApplicationPlugins are being booted
    // Inspect ContainerDelegator attachments
}
```

### Application - Request handling

**Location:** `Spryker\Shared\Application\Application`

**Purpose:** Sets up and boots ApplicationPlugins, selects the correct Kernel, and handles requests via HttpKernel.

**Key methods to debug:**

- `handle()`: Main request handling entry point (line 180)
- `registerPlugins()`: Registers all ApplicationPlugins (line 100)
- `registerPluginsAndBoot()`: Registers and boots ApplicationPlugins (line 131)

**What to look for:**

- Check which ApplicationPlugins are registered
- See when the Kernel is created and booted
- Verify container setup and switching

**Debug example:**

```php
// Add breakpoint in Application::handle()
public function handle(Request $request, int $type = self::MASTER_REQUEST, bool $catch = true): Response
{
    // Check if kernel exists in container
    // See how container is set up
    // Verify plugin registration timing
}
```

### Common debugging workflow

1. **Start with ContainerDelegator** - Check if the service is being requested and from which container
2. **Move to ControllerResolver** - If controller-related, see how it&apos;s being resolved
3. **Check Kernel setup** - Verify ApplicationPlugins and container configuration
4. **Review Application flow** - Understand the complete request lifecycle

### Enabling debug output

To see detailed container compilation information, set the debug flag to true:

In your `config/Shared/config_default.php`:

```php
$config[ApplicationConstants::ENABLE_APPLICATION_DEBUG] = true;
```

This enables:
- Container cache verification
- Detailed compiler pass output
- Service resolution logging

## Additional tips

### Clear application cache

If you encounter container compilation issues or suspect the cache is stale, clear the cache for the affected application.

**Clear cache for Zed:**

```bash
docker/sdk cli vendor/bin/console cache:clear
```

**Clear cache for Glue API:**

```bash
docker/sdk cli vendor/bin/glue cache:clear
```

**Clear cache for Glue Storefront API:**

```bash
docker/sdk cli GLUE_APPLICATION=GLUE_STOREFRONT vendor/bin/glue cache:clear
```

**Clear cache for Glue Backend API:**

```bash
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND vendor/bin/glue cache:clear
```

These commands clear the compiled container cache and force a fresh compilation on the next request.

### Verify container cache

If you need to manually inspect or remove specific container cache files:

```bash
# Clear the container cache
rm -rf data/cache/Zed/*/appSpryker_Shared_Application_Kernel*

# Rebuild the container
console container:build
```

### Check service availability

To verify if a service is available in the container, check the compiled container file:

```bash
# Location of compiled container
data/cache/Zed/{environment}/appSpryker_Shared_Application_Kernel_{Application}_{Environment}Container.php
```

Search for your service ID in this file to see if it was registered correctly.

### Module compilation check

If a core module doesn&apos;t have a container, check if it exists:

```bash
# Core module container location
vendor/spryker/{module-name}/src/Spryker/Zed/{ModuleName}/Service/Container/{ModuleName}ServiceContainer.php
```

## Next steps

- [Implementation and usage](/docs/dg/dev/architecture/dependency-injection/implementation-and-usage.html)
- [Best practices for Dependency Injection](/docs/dg/dev/architecture/dependency-injection/best-practices.html)
- [Dependency injection](/docs/dg/dev/architecture/dependency-injection.html)
</description>
            <pubDate>Wed, 28 Jan 2026 08:38:28 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/dependency-injection/troubleshooting.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/dependency-injection/troubleshooting.html</guid>
            
            
        </item>
        
        <item>
            <title>Troubleshooting installation</title>
            <description>This section describes common issues and solutions related to installing Spryker locally.

## Clear application cache

If you encounter compilation errors during installation or after setup, clear the cache for the affected application.

**Clear cache for Zed:**

```bash
docker/sdk cli vendor/bin/console cache:clear
```

**Clear cache for Glue API:**

```bash
docker/sdk cli vendor/bin/glue cache:clear
```

**Clear cache for Glue Storefront API:**

```bash
docker/sdk cli GLUE_APPLICATION=GLUE_STOREFRONT vendor/bin/glue cache:clear
```

**Clear cache for Glue Backend API:**

```bash
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND vendor/bin/glue cache:clear
```

These commands clear the compiled container cache and resolve most cache-related installation issues.

## Topics

- [Clear application cache](#clear-application-cache)
- [An error during front end setup](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/an-error-during-front-end-setup.html)
- [Demo data was imported incorrectly](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/demo-data-was-imported-incorrectly.html)
- [Docker daemon is not running](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/docker-daemon-is-not-running.html)
- [docker-sync cannot start](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/docker-sync-cannot-start.html)
- [Error 403 No valid crumb was included in the request](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/error-403-no-valid-crumb-was-included-in-the-request.html)
- [Node Sass does not yet support your current environment](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/node-saas-does-not-yet-support-your-current-environment.html)
- [Setup of new indexes throws an exception](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/setup-of-new-indexes-throws-an-exception.html)
- [Unable to bring up Mutagen Compose sidecar service](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/unable-to-bring-up-mutagen-compose-sidecar-service.html)
- [Vendor folder synchronization error](/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/vendor-folder-synchronization-error.html)
</description>
            <pubDate>Wed, 28 Jan 2026 08:38:28 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/troubleshooting-installation.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/set-up-spryker-locally/troubleshooting-installation/troubleshooting-installation.html</guid>
            
            
        </item>
        
        <item>
            <title>API Platform Enablement</title>
            <description>&lt;p&gt;This document describes how to create and enable API Platform resources in your Spryker project.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before creating API resources, ensure you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Integrated API Platform as described in &lt;a href=&quot;/docs/dg/dev/upgrade-and-migrate/integrate-api-platform.html&quot;&gt;How to integrate API Platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configured your application’s bundle files&lt;/li&gt;
&lt;li&gt;Configured API types as described in &lt;a href=&quot;/docs/dg/dev/architecture/api-platform/configuration.html&quot;&gt;API Platform Configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;creating-your-first-api-resource&quot;&gt;Creating your first API resource&lt;/h2&gt;
&lt;h3 id=&quot;define-the-resource-schema&quot;&gt;1. Define the resource schema&lt;/h3&gt;
&lt;p&gt;Create a schema file that defines your API resource structure. Schemas should be placed in &lt;code&gt;resources/api/{api-type}/&lt;/code&gt; directory within your module.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example: Customer resource for Back Office API&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/Customer/resources/api/backend/customers.yml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# yaml-language-server: $schema=../../../../../vendor/spryker/api-platform/resources/schemas/api-resource-schema-v1.json&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;shortName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;API&quot;&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Pyz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Glue&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Backend&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Provider&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CustomerBackendProvider&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;processor&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Pyz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Glue&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Backend&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Processor&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CustomerBackendProcessor&quot;&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;paginationEnabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paginationItemsPerPage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Post&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GetCollection&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Patch&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Delete&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;idCustomer&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;integer&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;customer.&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;writable&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;

        &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;or&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;contact.&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;openapiContext&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;test@spryker.com&quot;&lt;/span&gt;

        &lt;span class=&quot;na&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;person.&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;openapiContext&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;John&quot;&lt;/span&gt;

        &lt;span class=&quot;na&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;or&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;customer.&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;openapiContext&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Doe&quot;&lt;/span&gt;

        &lt;span class=&quot;na&quot;&gt;customerReference&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;reference&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;customer.&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;writable&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;create-validation-schema&quot;&gt;2. Create validation schema&lt;/h3&gt;
&lt;p&gt;Define validation rules in a separate validation schema file:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/Customer/resources/api/backend/customers.validation.yml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;NotBlank&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Email&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;NotBlank&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;NotBlank&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;constraints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
                  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;NotBlank&lt;/span&gt;
                  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Email&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;constraints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
                  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;NotBlank&lt;/span&gt;
                  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;na&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;implement-the-provider&quot;&gt;3. Implement the Provider&lt;/h3&gt;
&lt;p&gt;The Provider is responsible for fetching data (GET operations). Implement the &lt;code&gt;ProviderInterface&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/Customer/Api/Backend/Provider/CustomerBackendProvider.php&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Glue\Customer\Api\Backend\Provider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\Operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\State\Pagination\TraversablePaginator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\State\ProviderInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Glue\Customer\Business\CustomerFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Api\Backend\CustomersBackendResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProviderInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomerFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerFacade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;cd&quot;&gt;/**
     * @param \ApiPlatform\Metadata\Operation $operation
     * @param array&amp;lt;string, mixed&amp;gt; $uriVariables
     * @param array&amp;lt;string, mixed&amp;gt; $context
     *
     * @return object|array&amp;lt;object&amp;gt;|null
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Operation&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Single resource (GET /customers/{id})&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;customerReference&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;customerReference&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Collection (GET /customers)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCustomers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;?CustomersBackendResource&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customerFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;findCustomerByReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Map to API resource&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomersBackendResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fromArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getCustomers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TraversablePaginator&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$filters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;filters&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;page&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$itemsPerPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;itemsPerPage&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$customerCollection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customerFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCustomerCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$itemsPerPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCustomers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomersBackendResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fromArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

            &lt;span class=&quot;nv&quot;&gt;$resources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TraversablePaginator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ArrayObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$resources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$itemsPerPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$customerCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getTotalCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;implement-the-processor&quot;&gt;4. Implement the Processor&lt;/h3&gt;
&lt;p&gt;The Processor handles data modifications (POST, PUT, PATCH, DELETE). Implement the &lt;code&gt;ProcessorInterface&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/Customer/Api/Backend/Processor/CustomerBackendProcessor.php&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Glue\Customer\Api\Backend\Processor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\Operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\Patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\Metadata\Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApiPlatform\State\ProcessorInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Glue\Customer\Business\CustomerFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Api\Backend\CustomersBackendResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerBackendProcessor&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProcessorInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomerFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerFacade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;cd&quot;&gt;/**
     * @param mixed $data
     * @param \ApiPlatform\Metadata\Operation $operation
     * @param array&amp;lt;string, mixed&amp;gt; $uriVariables
     * @param array&amp;lt;string, mixed&amp;gt; $context
     *
     * @return mixed
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Operation&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customerFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;deleteCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;customerReference&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapToTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$savedCustomer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customerFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;createCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapToResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$savedCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$operation&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapToTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setCustomerReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$uriVariables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;customerReference&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$updatedCustomer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customerFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mapToResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$updatedCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapToTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CustomersBackendResource&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomerTransfer&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$transfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fromArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$transfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapToResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CustomerTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$transfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CustomersBackendResource&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomersBackendResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fromArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;generate-the-resource&quot;&gt;5. Generate the resource&lt;/h3&gt;
&lt;p&gt;Run the generation command to create the API resource class:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk cli &lt;span class=&quot;nv&quot;&gt;GLUE_APPLICATION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;GLUE_BACKEND glue api:generate backend
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This generates:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Generated/Api/Backend/CustomersBackendResource.php&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The generated class includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API Platform attributes (&lt;code&gt;#[ApiResource]&lt;/code&gt;, &lt;code&gt;#[ApiProperty]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Validation constraints (&lt;code&gt;#[Assert\NotBlank]&lt;/code&gt;, &lt;code&gt;#[Assert\Email]&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Public properties for all defined fields&lt;/li&gt;
&lt;li&gt;Getters and setters&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toArray()&lt;/code&gt; and &lt;code&gt;fromArray()&lt;/code&gt; methods&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;register-services-in-the-dependency-injection-container&quot;&gt;6. Register services in the Dependency Injection container&lt;/h3&gt;
&lt;p&gt;Make your Provider and Processor available through dependency injection:
markdo
&lt;code&gt;config/Glue/ApplicationServices.php&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ContainerConfigurator&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$configurator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$services&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$configurator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;autowire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;autoconfigure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Auto-discover services from your project modules&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$services&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Pyz\\Glue\\&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;../../../src/Pyz/Glue/&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;test-your-api&quot;&gt;7. Test your API&lt;/h3&gt;
&lt;p&gt;After generation, your API is immediately available:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# List all customers&lt;/span&gt;
GET /customers

&lt;span class=&quot;c&quot;&gt;# Get single customer&lt;/span&gt;
GET /customers/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;customerReference&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Create customer&lt;/span&gt;
POST /customers
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;email&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;john@example.com&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;firstName&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;John&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;lastName&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Doe&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Update customer&lt;/span&gt;
PATCH /customers/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;customerReference&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;firstName&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Jane&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Delete customer&lt;/span&gt;
DELETE /customers/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;customerReference&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;creating-codebucket-specific-resources&quot;&gt;Creating CodeBucket-specific resources&lt;/h2&gt;
&lt;p&gt;CodeBucket support enables you to create Code Bucket-specific API resource variants that are resolved at runtime based on the &lt;code&gt;APPLICATION_CODE_BUCKET&lt;/code&gt; environment constant.&lt;/p&gt;
&lt;h3 id=&quot;when-to-use-codebucket-resources&quot;&gt;When to use CodeBucket resources&lt;/h3&gt;
&lt;p&gt;Create CodeBucket variants when you need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code Bucket-specific properties (EU GDPR fields, tax rates, compliance data)&lt;/li&gt;
&lt;li&gt;Code Bucket-specific validation rules (country-specific requirements)&lt;/li&gt;
&lt;li&gt;Country-specific business logic&lt;/li&gt;
&lt;li&gt;Feature variations per Code Bucket&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quick-example&quot;&gt;Quick example&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Base resource:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/Customer/resources/api/backend/customers.yml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;shortName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Post&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;customerReference&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;EU-specific variant:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/CustomerEU/resources/api/backend/customers.resource.yml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customers&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;shortName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Customer&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;codeBucket&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;EU&lt;/span&gt;
  
  &lt;span class=&quot;na&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Post&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;customerReference&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# EU-specific properties&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;gdprConsentDate&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;GDPR&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;consent&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;dataPrivacyOfficerEmail&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;string&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;privacy&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;officer&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;contact&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Generate resources:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk cli &lt;span class=&quot;nv&quot;&gt;GLUE_APPLICATION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;GLUE_BACKEND glue api:generate backend
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This generates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CustomersBackendResource.php&lt;/code&gt; (base)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CustomersEUBackendResource.php&lt;/code&gt; (with &lt;code&gt;CODE_BUCKET = &apos;EU&apos;&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Runtime behavior:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Request to &lt;code&gt;glue.eu.spryker.local/customers&lt;/code&gt; → Uses &lt;code&gt;CustomersEUBackendResource&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Request to &lt;code&gt;glue.de.spryker.local/customers&lt;/code&gt; → Uses &lt;code&gt;CustomersBackendResource&lt;/code&gt; (fallback)&lt;/li&gt;
&lt;li&gt;Request to &lt;code&gt;glue.at.spryker.local/customers&lt;/code&gt; → Uses &lt;code&gt;CustomersBackendResource&lt;/code&gt; (or &lt;code&gt;CustomersATBackendResource&lt;/code&gt; if variant exists)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a comprehensive guide including Provider implementation and advanced scenarios, see &lt;a href=&quot;/docs/dg/dev/architecture/api-platform/code-buckets.html&quot;&gt;CodeBucket Support&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;api-types-and-use-cases&quot;&gt;API types and use cases&lt;/h2&gt;
&lt;p&gt;Spryker supports multiple API types for different use cases:&lt;/p&gt;
&lt;h3 id=&quot;storefront-api-glue&quot;&gt;Storefront API (Glue)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;storefront&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Module location:&lt;/strong&gt; &lt;code&gt;src/Spryker/{Module}/resources/api/storefront/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generated namespace:&lt;/strong&gt; &lt;code&gt;Generated\Api\Storefront&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Customer-facing APIs, mobile apps, PWAs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;back-office-api-glue&quot;&gt;Back Office API (Glue)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;backend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Module location:&lt;/strong&gt; &lt;code&gt;src/Pyz/Glue/{Module}/resources/api/backend/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generated namespace:&lt;/strong&gt; &lt;code&gt;Generated\Api\Backend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Admin panels, internal tools, ERP integrations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;merchant-portal-api&quot;&gt;Merchant Portal API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Type:&lt;/strong&gt; &lt;code&gt;merchant-portal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Module location:&lt;/strong&gt; &lt;code&gt;src/Spryker/{Module}/resources/api/merchant-portal/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generated namespace:&lt;/strong&gt; &lt;code&gt;Generated\Api\MerchantPortal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Marketplace merchant interfaces&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;schema-layering-and-inheritance&quot;&gt;Schema layering and inheritance&lt;/h2&gt;
&lt;p&gt;API Platform supports multi-layer schema definitions with automatic merging:&lt;/p&gt;
&lt;h3 id=&quot;core-layer&quot;&gt;Core layer&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;vendor/spryker/customer/resources/api/backend/customer.yml&lt;/code&gt; - Base definition&lt;/p&gt;
&lt;h3 id=&quot;feature-layer&quot;&gt;Feature layer&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src/SprykerFeature/CustomerRelationManagement/resources/api/backend/customer.yml&lt;/code&gt; - Feature enhancements&lt;/p&gt;
&lt;h3 id=&quot;project-layer&quot;&gt;Project layer&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src/Pyz/Glue/Customer/resources/api/backend/customer.yml&lt;/code&gt; - Project customizations&lt;/p&gt;
&lt;p&gt;The generator automatically merges these schemas with project layer taking precedence.&lt;/p&gt;
&lt;h2 id=&quot;debugging-resources&quot;&gt;Debugging resources&lt;/h2&gt;
&lt;p&gt;Use the debug command to inspect resources:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# List all resources&lt;/span&gt;
docker/sdk cli glue  api:debug &lt;span class=&quot;nt&quot;&gt;--list&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Show resource details&lt;/span&gt;
docker/sdk cli glue  api:debug customers &lt;span class=&quot;nt&quot;&gt;--api-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;backend

&lt;span class=&quot;c&quot;&gt;# Show merged schema&lt;/span&gt;
docker/sdk cli glue  api:debug customers &lt;span class=&quot;nt&quot;&gt;--api-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;backend &lt;span class=&quot;nt&quot;&gt;--show-merged&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Show source files&lt;/span&gt;
docker/sdk cli glue  api:debug customers &lt;span class=&quot;nt&quot;&gt;--api-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;backend &lt;span class=&quot;nt&quot;&gt;--show-sources&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/resource-schemas.html&quot;&gt;Resource Schemas&lt;/a&gt; - Deep dive into resource schema syntax&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/validation-schemas.html&quot;&gt;Validation Schemas&lt;/a&gt; - Define validation rules for your resources&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/code-buckets.html&quot;&gt;CodeBucket Support&lt;/a&gt; - Create Code Bucket-specific resources&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/testing.html&quot;&gt;API Platform Testing&lt;/a&gt; - Learn how to write tests for your API resources&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/architecture/api-platform/troubleshooting.html&quot;&gt;Troubleshooting&lt;/a&gt; - Common issues and solutions&lt;/li&gt;
&lt;/ul&gt;
</description>
            <pubDate>Tue, 27 Jan 2026 13:57:52 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/api-platform/enablement.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/api-platform/enablement.html</guid>
            
            
        </item>
        
        <item>
            <title>Customer Login overview</title>
            <description>&lt;p&gt;The &lt;em&gt;Customer Login&lt;/em&gt; feature with an enhanced secure password policy lets you prevent brute-force login attacks by configuring your project in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Block a Storefront user account for some time after a certain number of login attempts.&lt;/li&gt;
&lt;li&gt;Enforce the use of strong passwords by defining requirements for a password, like its length and allowed and forbidden characters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can define separate settings for a Storefront user and agent.&lt;/p&gt;
&lt;h2 id=&quot;demo-shop-default-configuration&quot;&gt;Demo Shop default configuration&lt;/h2&gt;
&lt;p&gt;The feature’s default configuration in the Spryker Demo Shop is as follows. When a user tries to log in and the number of unsuccessful login attempts reaches the preset limit (11 attempts for a Storefront user and 10 for an &lt;a href=&quot;/docs/pbc/all/user-management/latest/base-shop/agent-assist-feature-overview.html&quot;&gt;agent&lt;/a&gt;), the user account is locked out for some time (5 minutes for a Storefront user and 6 for an agent). After the last unsuccessful attempt, the user is notified that the ban is applied, and the user cannot log in until the ban expires.&lt;/p&gt;
&lt;p&gt;To minimize login issues for real customers, the ban is applied by the IP address, which means you can log in to the same user account from one IP address while being locked out of another IP address. All information about blocked accounts is stored in key-value store (Redis or Valkey).&lt;/p&gt;
&lt;p&gt;When registering an account or changing an old password in the Demo Shop, the password must contain a combination of alphabetic, numeric, and special characters. The alphabetic characters must also be of mixed case (for example, one lower case and one upper case), and the password length must be from 8 to 64 characters.&lt;/p&gt;
&lt;h2 id=&quot;security-concerns&quot;&gt;Security concerns&lt;/h2&gt;
&lt;p&gt;In order to enable brute-force protection, follow &lt;a href=&quot;/docs/about/all/releases/security-releases/security-release-notes-202306.0#introduced-changes-3&quot;&gt;this security release&lt;/a&gt;.&lt;/p&gt;
</description>
            <pubDate>Tue, 27 Jan 2026 08:46:40 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/customer-relationship-management/latest/base-shop/customer-account-management-feature-overview/customer-login-overview.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/customer-relationship-management/latest/base-shop/customer-account-management-feature-overview/customer-login-overview.html</guid>
            
            
        </item>
        
        <item>
            <title>Release notes 202512.0</title>
            <description>Spryker Cloud Commerce OS is an end-to-end solution for digital commerce. This document contains a business-level description of new features and improvements.

For information about installing Spryker, see [Getting started guide](/docs/dg/dev/development-getting-started-guide.html).

## Expanded B2B commerce capabilities

### Self-Service Portal models for asset-based catalogs &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt;

Self-Service Portal (SSP) models help operators manage complex equipment structures and help customers find compatible spare parts and service products faster in asset-based catalogs.

![Self-Service Assets](https://spryker.s3.eu-central-1.amazonaws.com/docs/About/all/releases/release-notes-202512.0.md/SSP-assets-page.png)

**What are SSP models?**
 SSP models let you group multiple assets into a single product family (for example, a machine type or series). Assets in the SSP are now directly connected to the product catalog, including compatible spare parts and service offerings, making the Self-Service Portal fully transactional.
For each model, a curated list of compatible spare parts and services can be maintained. When a customer browses the catalog or opens a product detail page, results are automatically filtered to show only items compatible with the selected model or asset, enabling accurate identification and immediate purchase.

**Key capabilities:**
- Group assets that belong to the same machinery type or generation.
- Maintain compatibility at the model level instead of the individual asset level.
- Assign spare part lists to models so buyers see only relevant products.
- Filter the storefront catalog by model, asset, serial number, or model code.
- Run compatibility checks from the product detail page.
- Support transactional self-service so customers purchase the correct items faster.

**Business benefits:**
- Improve spare part identification accuracy in self-service journeys.
- Reduce maintenance effort for asset-to-product mapping.
- Speed up after-sales purchases with asset-specific filtering.
- Scale after-sales revenue with automation and self-service.

Models is available in the Self-Service Portal Back Office and Storefront.

**Documentation:**
- [Self-Service Portal Models](/docs/pbc/all/self-service-portal/latest/ssp-model-management-feature-overview)
- [Self-Service Portal Asset Based Catalog](/docs/pbc/all/self-service-portal/latest/ssp-asset-based-catalog-feature-overview)
- [Self-Service Portal](/docs/pbc/all/self-service-portal/latest/self-service-portal)

### Merchant Portal file-based product import is now generally available &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

File-based product import in Merchant Portal moves from Early Access to General Availability, with reliability and UX improvements based on customer feedback.

![merchant-portal-import](https://spryker.s3.eu-central-1.amazonaws.com/docs/About/all/releases/release-notes-202507.0.md/merchant-portal-import.png)

**Key capabilities**
- Provide clear post-import results (success and errors) in the UI or as a downloadable CSV.
- Strengthen validations and safeguards to reduce failed imports and incorrect updates.
- Improve import consistency for production usage, including better messaging and translations where applicable.

**Business benefits**
- Faster merchant onboarding and ongoing catalog maintenance at scale.
- Lower support effort thanks to clearer feedback and import logs.
- Higher confidence running bulk imports in production environments.

**Documentation:**
- [Merchant Portal Import Products](/docs/pbc/all/product-information-management/latest/marketplace/manage-in-the-merchant-portal/import-products-ui)
- [Merchant Portal Import Product Offers](/docs/pbc/all/offer-management/latest/marketplace/import-offers-ui)
- [Install Merchant Portal Product Data Import](/docs/pbc/all/product-information-management/latest/marketplace/install-and-upgrade/install-features/install-the-merchant-product-data-import-feature)
- [Install Product Offer Data Import](/docs/pbc/all/offer-management/latest/marketplace/install-and-upgrade/install-features/install-the-marketplace-merchant-portal-product-offer-data-import-feature)

### Merchant Self-Registration &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt;

Merchant onboarding is simplified with a storefront entry point while keeping marketplace quality and compliance under control through Back Office review and approval.

![merchant-self-registration](https://spryker.s3.eu-central-1.amazonaws.com/docs/About/all/releases/release-notes-202512.0.md/Merchant-Self-Registration.png)

**Key capabilities:**
- Added a storefront-led merchant self-registration flow, allowing prospective merchants to submit an application which can be reviewed and approved in Back Office before merchant entities and users are created.

**Business benefits:**
- Reduced manual onboarding effort and improved consistency of merchant intake.
- Faster and more controlled merchant onboarding for marketplace operators.

**Documentation:**
- [Merchant Self-Registration](/docs/pbc/all/merchant-management/latest/marketplace/merchant-self-registration-feature-overview)
- [Install Merchant Self-Registration](/docs/pbc/all/merchant-management/latest/marketplace/install-and-upgrade/install-features/install-the-merchant-self-registration-feature)

### Agent assist order traceability &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Order traceability for Agent Assist flows is improved so operations and support teams can quickly see who submitted an order on behalf of a customer.

**Key capabilities:**
- Back Office now records and displays the submitting agent email for orders placed via Agent Assist, improving traceability and follow-up efficiency.

**Business benefits:**
- Faster issue resolution and clearer ownership for agent-created orders.
- Improved auditability for Agent Assist flows.

**Documentation:**
- [Agent Assist](/docs/pbc/all/user-management/latest/base-shop/agent-assist-feature-overview#setting-up-an-agent-user)
- [Install Agent Assist](/docs/pbc/all/user-management/latest/base-shop/install-and-upgrade/install-the-agent-assist-feature#install-feature-core)

### Merchant Portal dashboard improvements &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Merchant day to day catalog work is simplified in Merchant Portal by adding a clearer entry point to product management directly from the dashboard.

![merchant-portal-dashboard](https://spryker.s3.eu-central-1.amazonaws.com/docs/About/all/releases/release-notes-202512.0.md/merchant-portal-dashboard.png)

**Key capabilities**
- Added a Products widget to the Merchant Portal dashboard to improve discoverability of product management.

**Business benefits**
- Faster access to core catalog workflows for merchants.
- Less navigation effort for merchants managing large assortments.

### Storefront merchant profile improvements &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Storefront discovery is improved by making it easier for buyers to navigate from a merchant profile to that merchant&apos;s products with the right catalog filters already applied.

**Key capabilities**
- Added a &quot;Shop Merchant Products&quot; button on the merchant profile page that opens the product catalog with an active merchant filter.

**Business benefits**
- Faster product discovery for buyers shopping by merchant.
- Smoother path from merchant pages to relevant catalog results.

### Clearer UI in Back Office and Storefront &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Core UI patterns are made more consistent to improve scanability, reduce cognitive load, and provide clearer next steps in common workflows.

**Key capabilities**
- Introduced a global empty state component for tables with two variants:
- Implemented a semantic status pill color system (success, warning, error, neutral) for tables and internal pages, with one-line enforcement for better scanability.
- Replaced blocking Storefront notification banners with floating toast notifications (stacked, auto-dismiss, responsive positioning).

**Business benefits**
- Faster scanning and fewer mistakes when working with large datasets.
- Clearer guidance when tables are empty, improving task completion.
- Less disruptive Storefront messaging that keeps customers in context.

## Spryker AI: Built for Real Enterprise Commerce

### AI Foundation &lt;span class=&quot;inline-img&quot;&gt;![early-access](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/early-access.png)&lt;/span&gt;

AI Foundation is a provider-agnostic integration layer for building AI powered commerce capabilities in a consistent, maintainable way.

**Key capabilities:**
- New AiFoundation module compatible with Spryker architecture and existing AI related Eco packages.
- Multi provider support through a single interface (for example OpenAI, Azure OpenAI, AWS Bedrock, Google Gemini, Anthropic, local providers).
- Prompt based client method that supports file attachments for richer use cases.

**Business benefits:**
- Faster delivery of AI enabled commerce features through a reusable platform layer.
- Provider freedom: adopt or switch AI providers without rewriting feature logic, and choose the best provider and model per use case without rewriting code.
- Best fit provider per use case: use different providers and models for different needs.
- Lower maintenance effort by centralizing AI integration patterns and configuration.

**Documentation:**
- [AI Foundation](/docs/pbc/all/ai-foundation/latest/ai-foundation.html)
- [Use the AiFoundation module](/docs/pbc/all/ai-foundation/latest/ai-foundation.html)

### Spryker AI Commerce: Back Office Smart Product Management &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![early-access](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/early-access.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Back Office Smart Product Management now uses AI Foundation as its AI integration layer, replacing the previous direct OpenAI coupling. This gives customers provider and model choice while keeping existing Smart Product Management AI capabilities working.

&lt;figure class=&quot;video_container&quot;&gt;
    &lt;video width=&quot;100%&quot; height=&quot;auto&quot; controls aria-label=&quot;Smart PIM Product Translations&quot;&gt;
    &lt;source src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/About/all/releases/release-notes-202512.0.md/smart-pim-translations.m4v&quot; type=&quot;video/mp4&quot;&gt;
  &lt;/video&gt;
&lt;/figure&gt;

**Key capabilities:**
- Replace direct OpenAI integration in with AI Foundation as the unified AI layer.
- Enable provider and model selection based on customer needs (for example different providers for cost, latency, data residency, or model capabilities).

**Business benefits:**
- Protects existing customer functionality while enabling a standardized path for future AI enhancements.
- Reduces future integration effort and maintenance overhead for AI driven product management capabilities.

**Documentation:**
- [Smart Product Management](/docs/pbc/all/product-information-management/latest/base-shop/third-party-integrations/smart-product-management/smart-product-management)
- [Install Smart Product Management](/docs/pbc/all/product-information-management/latest/base-shop/third-party-integrations/smart-product-management/install-smart-product-management)

### Spryker AI Dev SDK &lt;span class=&quot;inline-img&quot;&gt;![early-access](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/early-access.png)&lt;/span&gt;

The AI Dev SDK improves local AI assisted development with an MCP server, Spryker aware context tools, and prompt library integration, so developers and AI assistants can work with accurate project information and reuse the same prompts across teams.

### Key capabilities

- Run a local MCP server for your Spryker project and extend it with custom tools and prompts.
- Give AI assistants access to Spryker contracts and data structures to reduce guesswork and implementation errors.
- Support OMS flow exploration by showing an order&apos;s current state and valid transitions, or listing transitions from any given state.
- Reuse and generate prompts from the shared Prompt Library via a typed PHP API.
- Keep console output integration friendly with quiet execution.

**Documentation:**
- [AI Dev Overview](/docs/dg/dev/ai/ai-dev/ai-dev-overview.html)
- [Configure the AiDev MCP server](/docs/dg/dev/ai/ai-dev/ai-dev-mcp-server.html)

## Open Architecture for the upcoming Innovation

### Reduced boilerplate via Symfony Dependency Injection support &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt;

Spryker uses the Dependency Inversion Principle to reduce tight coupling, improve unit testability, and provide a clear, extensible architecture. This approach enables autowiring and reduces the need for repetitive `Factory` and `DependencyProvider` wiring. This approach streamlines development and remains compatible with Symfony Dependency Injection conventions and tooling.

&lt;figure class=&quot;video_container&quot;&gt;
    &lt;video width=&quot;100%&quot; height=&quot;auto&quot; controls aria-label=&quot;Symfony Dependency Injection and Architecture Overview&quot;&gt;
    &lt;source src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202512/symfony_di.mp4&quot; type=&quot;video/mp4&quot;&gt;
  &lt;/video&gt;
&lt;/figure&gt;

**Key capabilities:**
- Reduced manual dependency wiring in your project code.
- Improved compatibility with Symfony bundles and Symfony Dependency Injection tooling, such as container introspection. Tools like `debug:container` help you visualize all services.
- Self-explanatory, declarative configuration.
- High performance through compiled and cached dependency injection.

**Business benefits:**
- **Code autowiring**: Reduce the boilerplate code you write and maintain by using Symfony Dependency Injection to automatically connect application components.
- **Faster feature delivery** by reducing repetitive scaffolding.
- **Easier onboarding** for developers who are already familiar with Symfony conventions.

**Documentation:**

- [Symfony Dependency Injection](/docs/dg/dev/architecture/dependency-injection.html)
- [Symfony Bundles in Spryker](/docs/dg/dev/architecture/symfony-bundles.html)

### API Platform &lt;span class=&quot;inline-img&quot;&gt;![early access](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/early-access.png)&lt;/span&gt; &lt;span class=&quot;inline-img&quot;&gt;![feature](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/feature.png)&lt;/span&gt;

The **API Platform** integration allows you to define API resources declaratively and automatically generate standards-compliant APIs with minimal manual effort. It reduces boilerplate, enforces consistency, and accelerates API development.

![API Platform](https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202512/api-platform-2.6-api.png)

**Key capabilities:**
- **Declarative API definition**: Define API resources using simple YAML schemas instead of writing repetitive controller and transfer logic.
- **Automatic endpoint generation**: Generate endpoints with built-in validation, pagination, and serialization that are ready for production use.
- **OpenAPI documentation**: Interactive OpenAPI documentation is generated automatically and stays in sync with your API definitions.
- **Consistent data contracts**: Enforce uniform data contracts and operation-specific validation rules across all APIs.
- **Clear separation of concerns**: Separate read and write logic using providers and processors for better maintainability and extensibility.

**Business benefits:**
- **Faster API development**: Reduce boilerplate and repetitive scaffolding, enabling faster feature delivery.
- **Easier onboarding**: Simplify API development for new teams and partners by providing clear documentation and structured guidance.

**Documentation:**
- [API Platform](/docs/dg/dev/architecture/api-platform.html)

### API tooling and integration documentation improvements &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

To make API development and partner onboarding easier, the following improvements are introduced:
- Enhanced the API documentation to be more structured and usable, with clearer terminology and guidance for integrations, including better support for exploring APIs and understanding data models.
- Enhanced documentation of the **Spryker data model**, including products, attributes, prices, and orders.
- Added a publicly available **Postman API collection** package, organized around practical &quot;happy path&quot; use cases and environments.

&lt;figure class=&quot;video_container&quot;&gt;
    &lt;video width=&quot;100%&quot; height=&quot;auto&quot; controls aria-label=&quot;Interactive API documentation walkthrough&quot;&gt;
    &lt;source src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202512/interactive_API_docs.mp4&quot; type=&quot;video/mp4&quot;&gt;
  &lt;/video&gt;
&lt;/figure&gt;

**Key capabilities:**
- Ready-to-run Postman collections for common API flows.
- Improved documentation structure and integration guidance for solution partners.

**Business benefits:**
- Faster API adoption and easier onboarding for developers and partners.
- Reduced integration effort and fewer misunderstandings for partners and new teams.

**Documentation:**
- [Integrations Documentation Portal](/docs/integrations/integrate-with-spryker.html)
- [Integrations Catalog](/docs/integrations/third-party-integrations.html)
- [Interactive API Playground](/docs/integrations/spryker-glue-api/storefront-api/api-references/storefront-api-marketplace-b2b-demo-shop-reference.html).
- [API reference with data model descriptions](/docs/integrations/spryker-glue-api/backend-api/api-references/backend-api-marketplace-b2b-demo-shop-reference.html). Expand each resposne to learn more about each field.
- [Postman Collections](https://github.com/spryker-community/glue-postman-collections)

### Publish &amp; Synchronize stability and scalability improvements &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Multiple enhancements improve the robustness and transparency of Publish &amp; Synchronize processing, especially when you operate in high-volume environments.

**Key capabilities:**
- Better resource monitoring and utilization for workers.
- Reduced noise from excessive INFO logs and more meaningful statistics and log output.
- Improved handling of slow queues through configurable waiting to avoid blocking other processing.
- Fixes for known stability issues reported across multiple customers.
- Improved error logging in the `queue:worker:start` output, including the queue name, failed message content, and exception chain.
- Cleaner processing output that suppresses &quot;all zeros&quot; lines and logs data only when metrics indicate work.
- Better ability to adjust processing batch size per queue to isolate problematic messages.

**Business benefits:**
- More stable P&amp;S execution under load.
- Easier scaling and debugging of complex event-driven catalog and offer updates.
- Reduced operational overhead for teams running large data volumes.
- Faster incident diagnosis for queue-related failures.
- Reduced log noise while keeping meaningful operational insights.

**Documentation and module releases:**

If you are using older versions, we recommend that you update to the referenced releases.

- [Implement Publish and Synchronization](/docs/dg/dev/backend-development/data-manipulation/data-publishing/implement-publish-and-synchronization.html)
- [Metrics and resource-aware worker configuration](/docs/dg/dev/backend-development/data-manipulation/event/configure-event-queues.html#metrics-and-resource-aware-worker-configuration)
- [Newest Publish &amp; Synchronize modules](/docs/dg/dev/guidelines/performance-guidelines/general-performance-guidelines.html#use-the-newest-modules)
- [Split heavy entities from publish and event queues](https://api.release.spryker.com/release-group/6027)
- [Batch processing of Propel entities](/docs/dg/dev/guidelines/performance-guidelines/performance-guidelines-batch-processing-propel-entities.html)

### Performance improvements &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Rendering of product items, cart pages, and URL resolution database queries has been optimized.

**Key capabilities:**
- Reduced repeated per-item loading patterns that previously caused multiple separate search calls for the cart, catalog listings, and PDP carousels.
- Improved widget and template behavior to avoid N-times Elasticsearch request patterns in common flows.
- Targeted cart performance improvements for large baskets.
- Eliminated unnecessary case-insensitive comparisons using `UPPER()` where the database collation is already case-insensitive.
- Improved performance for URL lookups in large datasets (reduces long-running queries and CPU pressure).

**Business benefits:**
- Faster page loads on high-traffic pages such as the cart, catalog, and PDP.
- Lower search infrastructure cost by cutting unnecessary requests.
- More predictable performance for customers with large carts and catalogs.
- Lower database CPU utilization.
- Faster request handling for URL-heavy flows (storefront and merchant portal routing scenarios).

**Documentation:**
- [Product review performance](/docs/dg/dev/guidelines/performance-guidelines/general-performance-guidelines.html#product-review-performance)
- [Cart performance configuration](/docs/pbc/all/cart-and-checkout/latest/cart-page-performance-configuration.html#cart-page-performance-configuration)

**Module Important technical releases:**
- [Cart page performance optimization](https://api.release.spryker.com/release-group/6107)
- [UPPER() function optimization for URL lookups](https://api.release.spryker.com/release-group/6124)

### Reliability improvements &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

**Key capabilities:**
- **Glue API**
  - Authentication is improved to avoid overloading JWT token payloads with large, mutable, session-relevant data, such as fine-grained permissions.
  - The API supports up-to-date permission and state resolution without relying on token reissuance.
- **Search**: Error handling in full-text search is improved to ensure that unexpected failures are logged and that users receive a consistent fallback experience.
- **OMS**: Order Management System processing is hardened against race conditions in which lock behavior can be unsafe in transactional or fast-response environments.

**Business benefits:**
- **Glue API**: Reduced risk of header-size-related failures in integrations that use extensive permission sets.
- **Search**: Faster production troubleshooting and fewer silent failures.
- **OMS**:
  - Fewer hard-to-reproduce concurrency issues in payment and order update flows.
  - Increased consistency of order state transitions under parallel event processing.

**Module releases:**
- [Glue API: Authentication improvements](https://api.release.spryker.com/release-group/6095)
- [Search: Improved error handling](https://api.release.spryker.com/release-group/6147)
- [OMS: Improved concurrency handling](https://api.release.spryker.com/release-group/5963)

### Infrastructure and runtime upgrades &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

Spryker updates its database support strategy to align MySQL and MariaDB versions with currently supported long-term support (LTS) releases. This change addresses the end of support for MySQL 5.7 and mitigates compatibility issues in production environments.

The update also includes changes to other components, such as PHP, RabbitMQ, and Bootstrap.

**Key capabilities:**
- Aligns supported **MySQL versions with modern LTS releases**, including MySQL 8.4.
- Continues support for **MariaDB 11.8** while ensuring secure and up-to-date LTS versions. Incremental rollouts are planned for early 2026.
- Enables **Redis compression by default** in demoshops to reduce memory footprint and improve cache efficiency.
- Ensures **PHP 8.4 readiness** through updates across modules and supporting tooling.
- Adds **RabbitMQ 4.1 support** to keep deployments current and benefit from performance improvements.
- Adds **Bootstrap 5** by default in Back Office.

**Business benefits:**
- Reduces memory usage and increases throughput for Valkey and Redis.
- Reduces security and operational risks by avoiding end-of-life database versions.
- Improved development–production parity, minimizing runtime incompatibilities.
- Future-proofs database, PHP, and RabbitMQ support to align with vendor support timelines and enterprise requirements.

**Documentation:**
- [Docker SDK service configuration](/docs/dg/dev/integrate-and-configure/configure-services.html)
- [System Requirements](/docs/dg/dev/system-requirements/latest/system-requirements.html)
- [Upgrade Back Office to Bootstrap 5](/docs/pbc/all/back-office/latest/base-shop/install-and-upgrade/upgrade-the-back-office-to-bootstrap-5.html)

### OpenTelemetry Instrumentation Update &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

This update improves OpenTelemetry instrumentation to increase trace accuracy and compatibility across Storefront, Backend API, and GLUE applications. You benefit from resolved naming inconsistencies and improved locale handling for monitoring plugins.

**Key capabilities:**
- Corrected root span naming for Storefront and Backend API to ensure consistent and meaningful traces.
- Fixed compatibility of `MonitoringRequestTransactionEventDispatcherPlugin` with GLUE applications by improving locale resolution logic.
- Improved robustness of monitoring setup to better support multiple application contexts without relying on hard-coded application name checks.

**Business benefits:**
- More accurate and consistent distributed tracing across all application types.
- Improved observability for GLUE-based APIs.

**Documentation:**
- [OpenTelemetry instrumentation](/docs/ca/dev/monitoring/spryker-monitoring-integration/opentelemetry-instrumentation.html)

### Web Profiler enhancements &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

You can now use an improved Web Profiler experience to better support performance investigations and troubleshooting during development:
- Fixed an incorrect template path used by `WebProfilerExternalHttpDataCollectorPlugin`.
- Added new profiling views for **Yves Ajax** and **Gateway** requests so you can more easily observe request and response flows.
- Introduced **Web Profiler improvements: External HTTP Logger**, which includes:
  - A data collector interface to capture and inspect third-party HTTP calls.
  - An in-memory logger to record external requests.
  - Public documentation describing configuration and usage.

**Key capabilities:**
- Improved visibility into third-party HTTP calls to help you detect bottlenecks, N+1 patterns, and slow dependencies.
- Broader profiling coverage across common Yves interaction patterns that you use in storefront development.

**Business benefits:**
- Faster root-cause analysis during development and quality assurance.
- Reduced time spent debugging external integrations and network-related performance regressions during development and testing.

**Module releases:**
- [Added Yves ajax and ZedRequest profiles to WebProfiler](https://api.release.spryker.com/release-group/6222)
- [Fix wrong template name in WebProfilerExternalHttpDataCollectorPlugin](https://api.release.spryker.com/release-group/6210)
- [External Custom Requests visible in Web Profiler](https://api.release.spryker.com/release-group/6162)

**Documentation:**
- [Web Profiler Widget for Yves AJAX](/docs/dg/dev/integrate-and-configure/integrate-development-tools/integrate-web-profiler-widget-for-yves.html)
- [Web Profiler for Backend Gateway](/docs/dg/dev/integrate-and-configure/integrate-development-tools/integrate-web-profiler-for-backend-gateway.html)
- [WebProfiler Widget monitoring of external HTTP calls](/docs/dg/dev/guidelines/performance-guidelines/external-http-requests.html)

### Faster local development and CI builds through Composer optimization &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

This release introduces a Composer plugin for Demo Shops that splits broad PSR-4 namespaces into **layer- and module-specific** namespaces during autoload generation. This approach reduces autoload scanning overhead and improves rendering and build performance.

**Key capabilities:**
- Converts general `Spryker\\` namespace mappings into granular mappings, such as `Spryker\\Zed\\&lt;Module&gt;\\` and `Spryker\\Yves\\&lt;Module&gt;\\`.
- Works in both development and production modes and applies consistently across Demo Shops.

**Business benefits:**
- Improved page rendering speed in Yves and back office during development.
- Faster container and image build times in CI and cloud environments, which improves delivery throughput.

**Module release:**
- [Composer Autoload Plugin](https://github.com/spryker/composer-autoload-plugin/releases/tag/0.1.0)

**Installation instructions:**
Inside your container execute the following command, answer `yes` when asked to trust this plugin:

```bash
composer require spryker/composer-autoload-plugin
```

### Improved developer productivity and efficiency &lt;span class=&quot;inline-img&quot;&gt;![improvement](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/user/intro-to-spryker/releases/release-notes/improvement.png)&lt;/span&gt;

**Key capabilities:**
- The coding standards remove the need for docblocks that duplicate already declared type information for methods and properties, which reduces noise and maintenance overhead.
- A new console helper lets you run a CLI command in a loop for extended periods, which is useful for high-load projects and operational workflows.
- You can override Webpack, JavaScript, and SCSS configurations for ZED at the project level.

**Business benefits:**
- You spend less developer time on non-value-adding code formatting tasks.
- You have less need for custom scripts to safely rerun console commands.

**Module releases:**
- [Adjust sniffer rules for Spryker modules to exclude docblocks from checks](https://api.release.spryker.com/release-group/6097)
- [Multi-process run console](/docs/dg/dev/backend-development/cronjobs/multi-process-run-console.html)
- [Overriding Webpack, JS, SCSS for ZED on the project level](/docs/dg/dev/frontend-development/latest/zed/overriding-webpack-js-scss-for-zed-on-the-project-level.html)
</description>
            <pubDate>Tue, 27 Jan 2026 08:41:50 +0000</pubDate>
            <link>https://docs.spryker.com/docs/about/all/releases/release-notes-202512.0.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/about/all/releases/release-notes-202512.0.html</guid>
            
            
        </item>
        
        <item>
            <title>Import file details: product_abstract.csv</title>
            <description>This document describes the `product_abstract.csv` file to configure [Abstract Product](/docs/pbc/all/product-information-management/latest/base-shop/feature-overviews/product-feature-overview/product-feature-overview.html) information in your Spryker Demo Shop.

## Import file dependencies

- [category.csv](/docs/pbc/all/product-information-management/latest/base-shop/import-and-export-data/categories-data-import/import-file-details-category.csv.html)
- [glossary.csv](/docs/pbc/all/miscellaneous/latest/import-and-export-data/import-file-details-glossary.csv.html)
- [tax.csv](/docs/pbc/all/tax-management/latest/base-shop/import-and-export-data/import-file-details-tax-sets.csv.html)



## Import file parameters

&lt;div class=&quot;width-100&quot;&gt;

| PARAMETER | REQUIRED | TYPE | REQUIREMENTS OR COMMENTS | DESCRIPTION |
| --- | --- | --- | --- | --- |
| category_key | &amp;check; | String | | Identifier of category key name. |
| category_product_order |  | Integer | | Order of the product presentation inside a category. |
| abstract_sku | &amp;check;  | String | | SKU identifier of the abstract product. |
| name.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *name.en_US* | &amp;check; | String |Locale data is dynamic in data importers. It means that ANY_LOCALE_NAME postifx can be changed, removed, and any number of columns with different locales can be added to the .csv files. | Name of the product in the specified location (US for our example). |
| url.{ANY_LOCALE_NAME}&lt;br&gt;Example parameter: *url.en_US* | &amp;check; | String | | URL page of the product image in the specified location (US for our example). |
| attribute_key_{NUMBER}&lt;br&gt;Example parameter: *attribute_key_1*&lt;br&gt; | &amp;check; (if this attribute is defined) | String | | Product attribute key for the attribute. Columns `attribute_key_{NUMBER}` and `value_{NUMBER}` should always come in pair. |
| value_{NUMBER}&lt;br&gt;Example parameter: *value_1*&lt;br&gt;|&amp;check; (if this attribute is defined) | String | | Product value for the attribute. |
| attribute_key_{NUMBER}.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *attribute_key_1.en_US*&lt;br&gt; |  | String | | Product attribute key, for the first attribute, translated in the specified locale (US for our example). Columns `attribute_key_{NUMBER}.{ANY_LOCALE_NAME}` and `value_{NUMBER}.{ANY_LOCALE_NAME}` should always come in pair.  |
| value_{NUMBER}.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *value_1.en_US*&lt;br&gt;| | String | | Product value for the attribute, translated in the specified locale (US for our example). |
| color_code |  | String | | Product color code. |
| description.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *description.en_US*  |  | String | | Product description, translated in the specified locale (US for our example). |
| tax_set_name |  | String | | Name of the tax set. |
| meta_title.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *meta_title.en_US* |  | String | | Meta title of the product in the specified locale (US for our example). |
| meta_keywords.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *meta_keywords.en_US* |  | String | | Meta keywords of the product in the specified locale (US for our example). |
| meta_description.{ANY_LOCALE_NAME}&lt;br&gt;Example value: *meta_description.en_US* || String | | Meta description of the product in the specified locale (US for our example). |
| new_from |  | Date | | To be considered a new product from this presented date. |
| new_to |  | String | | To be considered a new product until this presented date. |
| avalara_tax_code |  | String | | [Avalara tax code](/docs/pbc/all/tax-management/latest/base-shop/tax-feature-overview.html#avalara-system-for-automated-tax-compliance) for automated tax calculation. Add this field if Avalara is used for tax management. |

&lt;/div&gt;  


## Additional information

For each attribute, where N is a number starting from 1, without gaps, it&apos;s mandatory to have both fields:

- `attribute_key_N`
- `value_N`

For each attribute, where N is a number starting from 1, without gaps, it&apos;s mandatory to have both fields:

- `attribute_key_N.{ANY_LOCALE_NAME}`
- `value_N.{ANY_LOCALE_NAME}`

The number of attributes is not limited.

## Import template file and content example

| FILE | DESCRIPTION |
| --- | --- |
| [template_product_abstract.csv](https://spryker.s3.eu-central-1.amazonaws.com/docs/pbc/all/product-information-management/base-shop/import-and-export-data/import-file-details-product-abstract.csv.md/Template_product_abstract.csv) | Import file template with headers only. |
| [product_abstract.csv](https://spryker.s3.eu-central-1.amazonaws.com/docs/pbc/all/product-information-management/base-shop/import-and-export-data/import-file-details-product-abstract.csv.md/product_abstract.csv) | Exemplary import file with the Demo Shop data. |

## Import command

```bash
data:import:product-abstract
```
</description>
            <pubDate>Tue, 27 Jan 2026 08:40:55 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/product-information-management/latest/base-shop/import-and-export-data/products-data-import/import-file-details-product-abstract.csv.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/product-information-management/latest/base-shop/import-and-export-data/products-data-import/import-file-details-product-abstract.csv.html</guid>
            
            
        </item>
        
    </channel>
</rss>
