OpenAPI Development Skill
Context (Input)
- •Adding new OpenAPI endpoint factories under
src/Shared/Application/OpenApi/Factory/Endpoint/ - •Adding/editing request/response/schema factories under
src/Shared/Application/OpenApi/Factory/ - •Adding/editing sanitizers/augmenters/cleaners that transform the generated spec
- •Fixing OpenAPI validation errors from:
- •
make validate-openapi-spec(Spectral) - •
make openapi-diff - •
make schemathesis-validate
- •
Task (Function)
Develop and maintain OpenAPI specification generation in a way that:
- •Keeps code quality thresholds intact (complexity, style, architecture)
- •Preserves immutability when working with API Platform OpenAPI models (
with*()methods) - •Produces a spec that passes Spectral and stays diff-stable
Success Criteria:
- •
make generate-openapi-specproduces.github/openapi-spec/spec.yaml - •
make validate-openapi-specpasses
Architecture Overview
This service uses a layered OpenAPI customization approach:
text
src/Shared/Application/OpenApi/ ├── Augmenter/ # Add extra metadata/responses to operations ├── Builder/ # Build common OpenAPI pieces ├── Cleaner/ # Remove/normalize generated artifacts ├── Extractor/ # Extract example values / payload fragments ├── Factory/ # Endpoint/Request/Response/Schema/UriParameter factories ├── Sanitizer/ # Normalize pagination/path/query parameter behavior ├── ValueObject/ + Enum/ # Strongly typed OpenAPI-related value objects └── Factory/OpenApiFactory.php # Main coordinator (decorator)
config/services.yaml decorates API Platform’s OpenAPI factory with:
- •
App\Shared\Application\OpenApi\Factory\OpenApiFactory - •
!tagged_iterator 'app.openapi_endpoint_factory'
Key Principles (Keep Complexity Low)
- •Single Responsibility: one class = one transformation.
- •Immutability: prefer
with*()methods; avoid mutating nested arrays unless API Platform forces it. - •OPERATIONS constant: avoid chaining
withGet/withPost/...repeatedly. - •Readable guard clauses: prefer early returns over deep nesting.
- •Functional style:
array_map,array_filter,array_keysover procedural mutation.
See: reference/processor-patterns.md
How to Add New Components
Adding a New Sanitizer/Cleaner/Augmenter
- •Create a focused class under one of:
- •
src/Shared/Application/OpenApi/Sanitizer/ - •
src/Shared/Application/OpenApi/Cleaner/ - •
src/Shared/Application/OpenApi/Augmenter/
- •
- •Implement a single public entry method, e.g.
sanitize(OpenApi $openApi): OpenApi. - •Iterate paths using
array_keys($openApi->getPaths()->getPaths()). - •Apply changes per
PathItemusing anOPERATIONSconstant + dynamicwith/getcalls.
Adding a New Endpoint Factory
- •Implement
EndpointFactoryInterfaceundersrc/Shared/Application/OpenApi/Factory/Endpoint/. - •It is auto-tagged by
_instanceofinconfig/services.yaml. - •It will be invoked by
src/Shared/Application/OpenApi/Factory/OpenApiFactory.php.
Testing / Validation
Run locally (preferred order):
bash
make generate-openapi-spec make validate-openapi-spec make openapi-diff make schemathesis-validate
Notes:
- •
make validate-openapi-specruns./scripts/validate-openapi-spec.sh(Spectral). - •
make schemathesis-validateruns Examples and Coverage phases.
Related Skills
- •
complexity-managementfor refactoring when PHPInsights/PHPMD fails - •
documentation-syncwhen spec changes require docs updates