Shopware 6.2 comes with the beta version of a new API that will replace the current Sales Channel API.
tl;dr: The documentation can be found here:
The new endpoint is
store-api and your question right now is most probably: “Why?”
Bear with me, in this blog post I will give you the reasoning behind and the advantages of the new API.
The new API is fundamentally different from an architectural point of view and behaves differently, so it is natural to not just increment the version number of the Saleschannel API and call it a day. On top of that, the Store API is
not feature complete yet, because of the aforementioned architectural differences.
So there’s your “why”. Now let’s actually understand it.
The current Saleschannel API
To fully understand the reasoning behind the creation of a new API, let’s take a look at the bad things. (Although there are a lot of good as well, but that’s a different blog post.)
This diagram shows the big picture of how the Saleschannel API works:
What you can see here is: The Storefront and the Saleschannel API both depend on the same Services, but they use seperate controllers.
Where’s the problem, you ask?
During development, the feature parity is not guaranteed. Sure, we can manage that. Or can we? The reality shows, we can’t.
The available functionality in the API and the storefront right now has a noticable gap. A huge part of this is due how the API
is working in Shopware 6, since it’s geared toward working with entities. So the implementation of storefront features in the
Saleschannel API oftentimes is a lot of manual work.
I hope at this point you can understand why just bumping the API version and change a bit of fields is not a solution to this.
So what now? Enter our newest brainchild, the Store API
The Store API
Please note: At the time this blog post is published, the Store API is in the middle of being implemented. All new functionality
already uses it, so please use the Store API as much as possible. Over time, the Store API will become the only way to use
Storefront functionality over the API.
This diagram shows the big picture of how the Store API works:
So basically the Storefront is now forced to use the same controllers as the API. So all functionality implemented in either the API or the Storefront is automatically available in both. The API Controllers are Services, internally we call them Routes.
Here is an example of how a simple Route looks:
The logout function is annotated with an @Route annotation and available via the API. The Storefront calls the logout method directly from PHP.
In the example, the Response has no content, but let’s have a quick look at the CustomerResponse:
The magic here is simple: The object that is passed to the parent constructor is available automatically via the API.
The Storefront Bundle is using helper methods like
getCustomer() to receive PHP objects it can actually work with.
So each data source becomes a route in the store API and can then be used in the storefront. API first, the forcy way.
Important to note here:
- Route responses have to extend from the class
StoreApiResponse. By doing so, the result is automatically encoded to JSON when used by the API.
- Routes only implement a single functionality. Thus, a store page needs to get data from multiple routes.
- The Storefront only uses routes to read or write data.
Why is it important for you to understand thus? When creating plugins, you should create your own routes and follow the
pattern explained above.
Lastly, a bit about API aliases. The new Store API introduces so called Aliases. They are used to minimize the response size.
This is especially useful in mobile applications since the size of a response is crucial here.
Each object that is sent from the Store API to the client as a unique alias, called
apiAlias, which is always included in the response.
By sending a paramter
includes in the request body, you can choose which fields will be included in the response.
Here is an example using a request for a product and a price, including only certain fields:
The answer to the request above then only contains the requested fields: