Shopware 6 Hidden Gems #19: framework:schema — your shop’s real API spec, plugins included
Fabian Blechschmidt
The official Shopware API docs describe the stock API. Your shop doesn’t run the stock API. It runs stock plus the ERP connector’s custom entities, the subscription plugin’s extensions on product, your own entities from three projects ago. Every integration partner who codes against the official reference will faithfully implement an API that your shop doesn’t quite speak.
The fix is a one-liner that never made it beyond a bare mention in the command reference: your shop can dump its own OpenAPI specification — generated from the definitions actually registered in the container, custom entities, extensions and all.
That’s a complete OpenAPI 3 document of the Admin API (or Store API, with --store-api) of this installation. Feed it to the usual suspects:
# a browsable API doc for your integration partner
npx @redocly/cli build-docs admin-api.json
# a typed client for the middleware team
npx openapi-typescript admin-api.json -o shop-api.d.ts
Suddenly „what fields does your product entity have?“ is not a Slack thread anymore — it’s a generated artifact. Custom fields, entity extensions, plugin entities: all in there, because the generator walks the live definition registry, not a static file.
The other two formats
--schema-format (default simple) has three settings (Framework/Api/Command/DumpSchemaCommand.php:38-53):
openapi3 — the headline act above. Only this format distinguishes admin/store via --store-api.
entity-schema — the DAL’s own view of the world: every entity with fields, types, flags and associations as JSON. Less useful for API clients, very useful for tooling — diff it between deployments and you have a change report of your data model („which plugin update added a field to order?“). Note it clears the schema cache before generating, so it’s always current.
simple — the raw internal schema; mostly interesting as input for your own generators.
Two ergonomic details worth knowing: the output file argument is required, but - writes to stdout (progress chatter politely moves to stderr — someone thought about pipes), and --bundle-name restricts generation to one bundle’s definitions:
That last one is my favorite trick from this command: just your plugin’s API surface, reviewable in isolation — nice in CI to catch accidental API changes in a plugin release.
CI recipe: the API contract diff
Where this command earns its keep is automation. Dump the spec on every build and diff against the last release:
A plugin update silently adding a required field to an endpoint your partner’s middleware writes to? That’s a red diff in CI before it’s a production incident. Pair it with the sw-expect-packages header from part 3 of this series and integration breakage becomes something that happens in pipelines, not in support tickets.
(Runtime alternative: the same generator also serves /api/_info/openapi3.json on a running shop. The command version wins for CI because it needs no HTTP access and no credentials — a booted kernel is enough.)
TL;DR
bin/console framework:schema -s openapi3 --pretty out.json dumps the OpenAPI 3 spec of your shop — custom entities, extensions and plugin fields included; --store-api switches to the Store API, --bundle-name isolates one plugin, - pipes to stdout, and entity-schema format gives you a diffable dump of the whole DAL data model. Generated docs and typed clients from the actual API instead of the theoretical one. Documented: one line in the command reference.
Next up: the route defaults mini-framework — what _captcha, _noStore and _httpCache do to your controller routes, declaratively.
Generated a client from your shop’s spec? Drop me an email — curious which generator held up best!
Found in Shopware 6.7.0.0: Framework/Api/Command/DumpSchemaCommand.php — formats and options at lines 35-53, stdout handling at 58-61, cache-clearing for entity-schema at 77-79.