Using the Builder โ
Introduction โ
The Builder class is the recommended entry point for generating OpenAPI documents from PHP code. It provides a clean, fluent API and returns a Result object with access to the generated spec, scanned files, and validation diagnostics.
Basic usage โ
$result = (new \OpenApi\Builder())
->addSource('src/Controllers')
->addSource('src/Models')
->build();
echo $result->toYaml();Processing modes โ
The Builder supports three processing modes via setMode(string|Mode $mode):
Classic (default) โ
Scans source files for annotations/attributes and assembles the OpenAPI document via the Generator pipeline. This is the stable, production-ready mode.
use OpenApi\Builder\Mode;
$builder->setMode(Mode::CLASSIC);
// or: $builder->setMode('classic');Spec (beta) โ
Runs the new spec attributes pipeline end-to-end: Assembler โ Augmenters โ Compiler. Uses pure PHP 8.1+ attributes from the OpenApi\Spec namespace with typed DTOs and version-aware compilers.
$builder->setMode(Mode::SPEC);
// or: $builder->setMode('spec');Hybrid (beta) โ
Uses the classic Generator for scanning, then bridges the result into the spec pipeline's augmenters and compilers. A transition path for existing projects that want access to the new augmenter pipeline without rewriting all annotations.
$builder->setMode(Mode::HYBRID);
// or: $builder->setMode('hybrid');Choosing a mode
See the Processing Modes guide for a full comparison and migration path.
API โ
Sources โ
// Add sources one at a time
$builder->addSource('src/Controllers');
$builder->addSource(new \OpenApi\Utils\SourceFinder('src/', ['tests']));
// Or set all at once
$builder->setSources(['src/Controllers', 'src/Models']);Sources can be directory paths, file paths, \SplFileInfo, \Symfony\Component\Finder\Finder instances, or nested iterables of these.
Reflector sources (spec/hybrid mode) โ
In spec and hybrid mode, you can pass \Reflector instances (e.g. \ReflectionClass) directly instead of file paths. This is useful when you already have reflection objects available or want to build a spec from a specific set of classes without file scanning:
use OpenApi\Builder;
use OpenApi\Builder\Mode;
$result = (new Builder())
->setMode(Mode::SPEC)
->addSource([
new \ReflectionClass(App\Controllers\PetController::class),
new \ReflectionClass(App\Models\Pet::class),
])
->build();WARNING
Reflector sources are not supported in classic mode โ they require the spec or hybrid pipeline.
Version โ
$builder->setVersion('3.1.0');Sets the target OpenAPI version. Version resolution order:
- Explicit
setVersion()call (highest priority) - Version declared in the source
#[OA\OpenApi(version: '...')]attribute - Falls back to
3.0.0(classic) or3.1.0(spec/hybrid)
Logger โ
$builder->setLogger($psrLogger);Accepts any PSR-3 logger. Defaults to NullLogger (silent). The CLI command sets its own console logger.
Generator configuration (classic mode) โ
For advanced Generator configuration (custom analysers, processors, aliases, type resolvers), use withGenerator():
$builder->withGenerator(function (\OpenApi\Generator $generator) {
$generator->setAnalyser($customAnalyser);
$generator->setConfig(['operationId.hash' => false]);
$generator->withProcessorPipeline(function ($pipeline) {
$pipeline->remove(\OpenApi\Processors\CleanUnusedComponents::class);
});
});The callable receives a pre-configured Generator instance and may either modify it in-place or return a new instance.
Augmenter configuration (spec/hybrid mode) โ
For spec and hybrid modes, use withAugmenters() to configure the augmenter pipeline:
use OpenApi\Augmenter;
$builder->withAugmenters(function (\OpenApi\Utils\Pipeline $pipeline) {
// Disable an augmenter
$pipeline->get(Augmenter\Cleanup::class)?->setEnabled(false);
// Configure operationId generation
$pipeline->get(Augmenter\OperationIds::class)?->setHash(true);
// Filter to specific paths/tags
$pipeline->get(Augmenter\PathFilter::class)
?->setPathFilter('/^\/api\/v2/')
?->setTagFilter('/^(Users|Products)$/');
// Insert a custom augmenter
$pipeline->insert(new CustomAugmenter(), Augmenter\Inheritance::class);
// Remove an augmenter entirely
$pipeline->remove(Augmenter\EnumDescriptions::class);
});The pipeline is grouped into three phases that run in order: resolve โ reduce โ augment. See the Augmenters reference for the full list and their configuration options.
Attribute factory configuration (spec mode) โ
Use withAttributeFactory() to add custom attribute translators:
use OpenApi\Utils\AttributeFactory;
$builder->withAttributeFactory(function (AttributeFactory $factory): void {
$factory->getTranslators()->add(new SymfonyValidationTranslator());
});Translators convert non-OA attributes (e.g. Symfony #[Assert\*], framework route annotations) into spec DTOs during assembly.
Result โ
The build() method returns a \OpenApi\Builder\Result instance:
$result = $builder->build();
$result->isValid(); // bool โ true if a spec was generated
$result->toArray(); // array โ the spec as a PHP array
$result->toJson(); // string โ JSON output
$result->toYaml(); // string โ YAML output
$result->files(); // string[] โ scanned source files
$result->log(); // array โ all log entries [{level, message}, ...]
$result->warnings(); // string[] โ warning messages
$result->errors(); // string[] โ error messages
$result->specification(); // the final `Specification` instanceFull example (spec mode) โ
use OpenApi\Builder;
use OpenApi\Builder\Mode;
use OpenApi\Augmenter;
$result = (new Builder())
->setMode(Mode::SPEC)
->setVersion('3.1.0')
->addSource('src/Api')
->withAugmenters(function (\OpenApi\Utils\Pipeline $pipeline) {
$pipeline->get(Augmenter\Cleanup::class)?->setEnabled(false);
$pipeline->get(Augmenter\OperationIds::class)?->setHash(true);
})
->build();
echo $result->toYaml();