docs/guide/modes.md
Swagger-php supports three processing modes that control how your source code is transformed into an OpenAPI document. Each uses a different internal pipeline.
| Classic | Hybrid | Spec | |
|---|---|---|---|
| Status | Stable | Beta | Beta |
| Attributes | OpenApi\Attributes | OpenApi\Attributes | OpenApi\Spec |
| Annotations | Yes | Yes | No |
| Pipeline | Generator โ Processors | Assembler โ Resolver โ HybridBridge โ Augmenters โ Compiler | Assembler โ Resolver โ Augmenters โ Compiler |
| Best for | Existing projects | Gradual migration | New projects |
The classic mode scans source files for OpenApi\Attributes (and legacy OpenApi\Annotations) and assembles the OpenAPI document via the Generator pipeline with its processor chain.
use OpenApi\Builder;
$result = (new Builder())
->addSource('src/')
->build();
$result->toYaml();
Classic mode gives you access to the full Generator API including custom processors, analysers, and configuration options via withGenerator().
Spec mode is a ground-up reimplementation of the pipeline using attributes from the OpenApi\Spec namespace. It introduces:
merge()/contained() maps replace reflection-based nestinguse OpenApi\Builder;
use OpenApi\Builder\Mode;
$result = (new Builder())
->setMode(Mode::SPEC)
->addSource('src/')
->build();
$result->toYaml();
Spec mode uses the OpenApi\Spec namespace (use OpenApi\Spec as OA;). See Using Spec Attributes for a full guide.
::: warning Beta Spec mode is mostly feature-complete but still beta. The attribute API may evolve based on feedback before being promoted to default in a future major version. :::
Hybrid mode uses the classic Generator for scanning (so your existing OpenApi\Attributes annotations work unchanged), then bridges the result into the spec pipeline's augmenters and compilers.
This gives you the augmenter pipeline and version-aware compilation without rewriting any attribute code.
use OpenApi\Builder;
use OpenApi\Builder\Mode;
$result = (new Builder())
->setMode(Mode::HYBRID)
->addSource('src/')
->build();
$result->toYaml();
Hybrid mode is the recommended transition path for existing projects that want to benefit from the new pipeline incrementally.
::: warning Disclaimer
Hybrid mode will not work in heavily customized projects like NelmioApiDocBundle, or in projects adding custom processors.
:::
./vendor/bin/openapi src/ --mode spec -o openapi.yaml
./vendor/bin/openapi src/ --mode hybrid -o openapi.yaml
use OpenApi\Builder;
use OpenApi\Builder\Mode;
$builder->setMode(Mode::SPEC);
// or: $builder->setMode('spec');
The modes aim for equivalent output from the same source, but differ in what they accept and in how they can be configured:
| Behavior | Classic | Hybrid | Spec |
|---|---|---|---|
Annotation support (/** @OA\... */) | Yes | Yes | No |
MergeJsonContent / MergeXmlContent | Yes | Yes | Yes (via OA\MediaType\Json) |
Processor chain (withGenerator()) | Yes | Scanning only (MergeJsonContent/MergeXmlContent) | No |
Resolver (withResolver()) | No | Yes (Resolver\Reflection by default) | Yes (Resolver\Reflection by default) |
Augmenter pipeline (withAugmenters()) | No | Yes | Yes |
| Version-aware compilation | No (single serializer) | Yes | Yes |
The recommended migration path is:
Classic โ Hybrid โ change setMode(Mode::HYBRID) and verify output is unchanged. No code changes needed. This gives you access to the augmenter pipeline.
Hybrid โ Spec โ when starting new code, use OpenApi\Spec attributes. Existing OpenApi\Attributes code continues to work via hybrid mode.
Full Spec โ once all code uses OpenApi\Spec attributes, switch to setMode(Mode::SPEC).
::: tip Version timeline
setMode() and all classic code deprecated.setMode() removed. Spec becomes default. Spec code might move to OpenApi\Attributes.
:::