Skip to content

๐Ÿงช Processing Modes โ€‹

Swagger-php supports three processing modes, which control how source code is turned into an OpenAPI document. Each uses a different internal pipeline.

Overview โ€‹

ClassicHybridSpec
StatusStableBetaBeta
AttributesOpenApi\AttributesOpenApi\AttributesOpenApi\Spec
AnnotationsYesYesNo
PipelineGenerator โ†’ ProcessorsAssembler โ†’ Resolver โ†’ HybridBridge โ†’ Augmenters โ†’ CompilerAssembler โ†’ Resolver โ†’ Augmenters โ†’ Compiler

Classic (default) โ€‹

Classic mode scans source files for OpenApi\Attributes (and legacy OpenApi\Annotations) and builds the OpenAPI document through the Generator and its processor chain.

php
use OpenApi\Builder;

$result = (new Builder())
    ->addSource('src/')
    ->build();

$result->toYaml();

Classic mode gives access to the full Generator API through withGenerator(), including custom processors, analysers and configuration options.

Spec (beta) โ€‹

Spec mode reimplements the pipeline from the ground up, using attributes from the OpenApi\Spec namespace. It introduces:

  • Typed DTOs: attributes are simple data containers with constructor-promoted properties
  • Slot-map nesting: explicit merge()/contained() maps replace reflection-based nesting
  • Grouped augmenters: a three-phase pipeline (resolve โ†’ reduce โ†’ augment) with explicit ordering
  • Version-aware compilers: separate compilers for OpenAPI 3.0, 3.1 and 3.2
php
use 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.

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 (beta) โ€‹

Hybrid mode scans with the classic Generator, so existing OpenApi\Attributes work unchanged. It 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.

php
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 move to the new pipeline step by step.

Disclaimer

Hybrid mode will not work in heavily customized projects like NelmioApiDocBundle, or in projects adding custom processors.

Switching modes โ€‹

CLI โ€‹

shell
./vendor/bin/openapi src/ --mode spec -o openapi.yaml
./vendor/bin/openapi src/ --mode hybrid -o openapi.yaml

PHP โ€‹

php
use OpenApi\Builder;
use OpenApi\Builder\Mode;

$builder->setMode(Mode::SPEC);
// or: $builder->setMode('spec');

Behavioral differences โ€‹

The modes aim for equivalent output from the same source, but differ in what they accept and in how they can be configured:

BehaviorClassicHybridSpec
Annotation support (/** @OA\... */)YesYesNo
MergeJsonContent / MergeXmlContentYesYesYes (via OA\MediaType\Json)
Processor chain (withGenerator())YesScanning only (MergeJsonContent/MergeXmlContent)No
Resolver (withResolver())NoYes (Resolver\Reflection by default)Yes (Resolver\Reflection by default)
Augmenter pipeline (withAugmenters())NoYesYes
Contributions (withSpecification())NoYesYes
Version-aware compilationNo (single serializer)YesYes
Unreferenced componentsKeptRemoved, with a noticeRemoved, with a notice
-c / -D keysProcessors, generator.*Augmenters, generator.*Augmenters

Classic removes unreferenced components only when asked, with -c cleanUnusedComponents.enabled=true. Hybrid and spec remove them by default and log how many at notice level. -c cleanup.enabled=false keeps them, or in PHP:

php
use OpenApi\Augmenter;
use OpenApi\Utils\Pipeline;

$builder->withAugmenters(fn (Pipeline $pipeline) => $pipeline->get(Augmenter\Cleanup::class)->setEnabled(false));

See Augmenters for the Cleanup options.

Migration path โ€‹

The recommended migration path is:

  1. Classic โ†’ Hybrid: change to setMode(Mode::HYBRID). No code changes are needed, and the augmenter pipeline becomes available. Output stays the same, with two exceptions:

    • Components that no path references are removed, including a schema kept only for client code generation. Behavioral differences has the switch that keeps them.

    • -c takes augmenter keys rather than processor keys, apart from generator.*. --mode hybrid -D src lists them.

  2. Hybrid โ†’ Spec: when starting new code, use OpenApi\Spec attributes. Existing OpenApi\Attributes code keeps working through hybrid mode. The spec attributes are not a one-for-one rename of the classic ones. A reusable attribute takes a single component: key, where classic spells the key after its own type (schema:, parameter:, request:, securityScheme:). See Components.

  3. Full Spec: once all code uses OpenApi\Spec attributes, switch to setMode(Mode::SPEC).

Version timeline

  • v6: spec and hybrid ship as opt-in beta. Classic remains the default.
  • v7: hybrid becomes the default mode. Classic is still available. setMode() and all classic code are deprecated.
  • v8: classic is removed, and so is setMode(). Spec becomes the default. Spec attributes move to OpenApi\Attributes. For code already written against OpenApi\Spec, that move is one use line per file. Coming from classic, the component keys are renamed as well.