Unofficial API aware guidelines for Shopware 6
This is a collection of insights and things we've seen during plugin reviews, app reviews and projects for Shopware 6. We hope this is helpful for anyone who wants to make their app, plugin or project headless-ready and API aware. Many thanks to the awesome Maciek Kucmus who did all the hard work to put this together. I only revised and extended some parts. Also feel free to comment or ping me if we forgot something or you want to add more important points to this checklist.
Content
Why should you provide an API?
Providing a REST API for Shopware is crucial for enabling headless applications and improving overall functionality. Here are some reasons for implementing an API:
- Flexibility
A REST API allows headless apps to interact with the Shopware platform in a decoupled manner. This enables developers to build custom front-end experiences using any technology stack they prefer, fostering innovation and adaptability. - Scalability
By providing a REST API, Shopware can support multiple headless apps simultaneously. This scalability allows for seamless integration with various front-end applications, including mobile apps, progressive web apps, and even voice assistants. - Customization
With a REST API, developers can extend the functionality of Shopware to meet specific business requirements. This empowers the creation of tailored experiences and unique features for headless apps, driving competitive advantage. - Third-party Integration
A REST API significantly simplifies the process of integrating third-party services and applications with Shopware. This opens up opportunities for partnerships, integrations with other platforms, and the creation of a robust ecosystem of extensions. - Future-proofing
As the e-commerce landscape evolves, having a well-designed API ensures that your plugin or app can adapt to new technologies and consumer demands without requiring a complete overhaul. - Performance Optimization
APIs can be designed to deliver only the necessary data, reducing payload sizes and improving overall application performance, especially crucial for mobile and low-bandwidth scenarios.
Further information on the store API concept can be found here.
The does and don'ts
Does - API aware - Shopware 6
1.) Always provide store-api endpoints for your functionalities when the interaction between end-user (customer) and admin is required.
Being aware of a fact, that someone wants to use your feature outside the standard storefront is crucial. Let the detached frontend applications interact with your app/plugin using store-api endpoints as well.
Example 1:
My app provides a form to write and store additional information of the customized product in the checkout.
Possible solutions:
- Expose an endpoint to get the information whether form should be displayed with all required details like fields, action URL and so on.
- Expose an endpoint to receive a form data sent by an app
Example 2:
My extension adds another payment provider and allows users to display a credit card component.
Possible solutions:
- Expose an endpoint to init and get the payment intent session
- Provide an endpoint to save the token after credit card is confirmed ans authorized
2.) Document the endpoints
The best, and fastest way to achieve a good documentation is to provide OpenAPI Schema. This standard is used in existing controllers within a Core and Shopware plugins. The result enables client libraries to generate live documentation (i.e. Swagger) or the API clients for almost every programming language. The good example is @shopware/api-client which is used in Shopware Composable Frontends.
3.) Provide UI Components
If your module provides some views in twig or html, it won't be fetched and displayed in a headless app. In that case, please provide required endpoints and README/docs that explain how and when to use it to display your module's feature as intended.
Bonus: Provide a npm package that add the basic UI components for frontend applications like NUXT/Vue.
Don'ts - API aware - Shopware 6
1.) Don't rely only on PHP sessions
As detached client application does not have an access to the PHP session directly, keep in mind that only a context token can connect the context of an user with the session in the server.
2.) Don't put additional logic or DB calls in Controllers
Avoiding additional logic or database calls in controllers for Shopware 6 is crucial for several reasons. First, it promotes separation of concerns, keeping controllers focused on routing rather than business logic. Second, encapsulating logic in services enhances reusability and maintainability, making it easier to test and update. Third, this approach ensures API consistency across various interfaces, which is essential for headless setups. Lastly, it improves performance and flexibility, allowing for optimized database interactions and easier adaptation to different frontend technologies.
3.) Don't rely only on Page Loader events
Page loaders aren't executed for API endpoints. If your functionality alters the way of displaying some component, or changes a price, or saves something in the database, It's highly possible that this won't work for a headless app. The action will be omitted.
Example:
The module displays a special message for a customer in a checkout page if a customer is not from origin Country of the seller.
Possible solutions:
- Provide an endpoint that check's if the customer should see the additional message that can be used in the detached checkout app
- Alter the customer entity (via extensions property) that keeps that information that can be used later on
API aware Checklist
Super fast and simple Checklist you can use to check your plugin/app.
- Business logic is also covered and reachable via store-api scope endpoint(s) - focus on logic availability
- All store-api endpoints are prefixed by your module's sluggyfied name/code: /store-api/my-super-module/form (my-supper-module) to avoid naming collisions among other endpoints.
- All provided endpoints are documented using OpenAPI Schema.
Bonus: Types are correct generated and tested with api-gen package.