methorz / openapi-generator
Automatic OpenAPI 3.0 specification generator from routes and DTOs
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/methorz/openapi-generator
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- psr/container: ^1.1 || ^2.0
- symfony/console: ^6.0 || ^7.0
- symfony/yaml: ^6.0 || ^7.0
Requires (Dev)
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^11.0 || ^12.0
- psr/http-message: ^1.1 || ^2.0
- psr/http-server-middleware: ^1.0
- slevomat/coding-standard: ^8.25
- squizlabs/php_codesniffer: ^4.0
- symfony/validator: ^6.0 || ^7.0
This package is auto-updated.
Last update: 2025-12-01 09:32:25 UTC
README
Automatic OpenAPI 3.0 specification generator from routes and DTOs
Automatically generates OpenAPI specifications by analyzing your application's routes and Data Transfer Objects (DTOs). Perfect for Mezzio, Laminas, and any PSR-15 application.
โจ Features
- ๐ Automatic Generation: Scans routes and DTOs to generate complete OpenAPI specs
- ๐ DTO Analysis: Extracts request/response schemas from PHP DTOs with property promotion
- โ Validation Integration: Reads Symfony Validator attributes for schema constraints
- ๐ฏ Handler Detection: Automatically finds request and response DTOs in handlers
- ๐ฆ Multiple Formats: Generates both YAML and JSON outputs
- ๐ง Zero Configuration: Works out-of-the-box with sensible defaults
- ๐จ Customizable: Configure via application config
- ๐ Nested DTOs: Automatically generates schemas for nested DTO references
- ๐ Collections: Supports typed arrays with
@param array<Type>PHPDoc - ๐ฒ Enums: Full support for backed and unit enums (PHP 8.1+)
- ๐ Union Types: Generates
oneOfschemas for union types (PHP 8.0+) - โก Performance: Schema caching for efficient generation
๐ Requirements
This package requires PHP 8.2+ and uses the following runtime dependencies:
| Package | Purpose | Framework Required? |
|---|---|---|
psr/container |
PSR-11 Container Interface | โ No |
symfony/console |
CLI command handling | โ No (standalone utility) |
symfony/yaml |
YAML file parsing/writing | โ No (standalone utility) |
Note: The Symfony packages used are standalone utility libraries, not framework components. They work independently without the Symfony framework and are used by many non-Symfony projects (Composer, PHPStan, PHPUnit, etc.).
๐ฆ Installation
composer require methorz/openapi-generator
๐ Quick Start
1. Register the Command
Add to your application's command configuration:
// config/autoload/dependencies.global.php use Methorz\OpenApi\Command\GenerateOpenApiCommand; return [ 'dependencies' => [ 'factories' => [ GenerateOpenApiCommand::class => function ($container) { return new GenerateOpenApiCommand($container); }, ], ], ];
2. Generate Specification
php bin/console openapi:generate
This will create:
public/openapi.yaml- YAML formatpublic/openapi.json- JSON format
๐ Usage
Basic Configuration
// config/autoload/openapi.global.php return [ 'openapi' => [ 'title' => 'My API', 'version' => '1.0.0', ], ];
Example Handler
The generator automatically analyzes your handlers:
namespace App\Handler; use App\Request\CreateItemRequest; use App\Response\ItemResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; final class CreateItemHandler implements RequestHandlerInterface { public function handle( ServerRequestInterface $request, CreateItemRequest $dto // โ Request DTO detected ): ItemResponse { // โ Response DTO detected // Handler logic... } }
Example Request DTO
namespace App\Request; use Symfony\Component\Validator\Constraints as Assert; final readonly class CreateItemRequest { public function __construct( #[Assert\NotBlank] #[Assert\Length(min: 3, max: 100)] public string $name, #[Assert\NotBlank] #[Assert\Length(min: 10, max: 500)] public string $description, #[Assert\Email] public string $email, ) {} }
Generated Schema:
components: schemas: CreateItemRequest: type: object required: - name - description - email properties: name: type: string minLength: 3 maxLength: 100 description: type: string minLength: 10 maxLength: 500 email: type: string format: email
๐ Supported Validation Attributes
The generator extracts constraints from Symfony Validator attributes:
| Attribute | OpenAPI Property |
|---|---|
@Assert\NotBlank |
required: true |
@Assert\Length(min, max) |
minLength, maxLength |
@Assert\Range(min, max) |
minimum, maximum |
@Assert\Email |
format: email |
@Assert\Url |
format: uri |
@Assert\Uuid |
format: uuid |
๐ Advanced Features
Enum Support
Generates enum schemas from PHP 8.1+ backed enums:
enum StatusEnum: string { case DRAFT = 'draft'; case ACTIVE = 'active'; case ARCHIVED = 'archived'; } final readonly class CreateItemRequest { public function __construct( public StatusEnum $status, ) {} }
Generated Schema:
CreateItemRequest: type: object properties: status: type: string enum: ['draft', 'active', 'archived']
Nested DTOs
Automatically generates schemas for nested DTO objects:
final readonly class AddressDto { public function __construct( #[Assert\NotBlank] public string $street, #[Assert\NotBlank] public string $city, public ?string $country = null, ) {} } final readonly class CreateUserRequest { public function __construct( public string $name, public AddressDto $address, // โ Nested DTO public ?AddressDto $billingAddress = null, // โ Nullable nested DTO ) {} }
Generated Schema:
CreateUserRequest: type: object required: ['name', 'address'] properties: name: type: string address: $ref: '#/components/schemas/AddressDto' billingAddress: $ref: '#/components/schemas/AddressDto' nullable: true AddressDto: type: object required: ['street', 'city'] properties: street: type: string city: type: string country: type: string nullable: true
Typed Collections
Supports typed arrays using PHPDoc annotations:
/** * @param array<int, AddressDto> $addresses * @param array<string> $tags */ final readonly class CreateOrderRequest { public function __construct( public string $orderId, public array $addresses, public array $tags, ) {} }
Generated Schema:
CreateOrderRequest: type: object properties: orderId: type: string addresses: type: array items: $ref: '#/components/schemas/AddressDto' tags: type: array items: type: string
Union Types
Generates oneOf schemas for union types:
final readonly class FlexibleRequest { public function __construct( public string|int $identifier, // โ Union type ) {} }
Generated Schema:
FlexibleRequest: type: object properties: identifier: oneOf: - type: string - type: integer
๐ฏ Features
Route Detection
Scans your application's route configuration:
// config/autoload/routes.global.php return [ 'routes' => [ [ 'path' => '/api/v1/items', 'middleware' => [CreateItemHandler::class], 'allowed_methods' => ['POST'], ], ], ];
Automatic Operation Generation
Creates OpenAPI operations with:
- HTTP method (GET, POST, PUT, DELETE, etc.)
- Path parameters (extracted from
{id}patterns) - Request body (for POST/PUT/PATCH)
- Response schemas
- Summary and operationId
- Tags (from module namespace)
Path Parameters
Automatically detects and types path parameters:
'/api/v1/items/{id}' โ parameter: id (format: uuid) '/api/v1/users/{userId}' โ parameter: userId (type: integer)
๐ Generated Output
OpenAPI Structure
openapi: 3.0.0 info: title: My API version: 1.0.0 description: Automatically generated from routes and DTOs servers: - url: http://localhost:8080 description: Local development paths: /api/v1/items: post: operationId: createItem summary: create item tags: - Items requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateItemRequest' responses: 201: description: Success content: application/json: schema: $ref: '#/components/schemas/ItemResponse' 400: description: Bad Request 404: description: Not Found components: schemas: CreateItemRequest: # ... schema definition ItemResponse: # ... schema definition
๐ง Configuration
Full Configuration Example
// config/autoload/openapi.global.php return [ 'openapi' => [ 'title' => 'My API', 'version' => '1.0.0', 'description' => 'API for managing items', 'servers' => [ [ 'url' => 'https://api.example.com', 'description' => 'Production', ], [ 'url' => 'http://localhost:8080', 'description' => 'Development', ], ], ], ];
๐ Integration with Swagger UI
View your generated OpenAPI specification:
# Install Swagger UI composer require swagger-api/swagger-ui # Access at: http://localhost:8080/swagger-ui
Or use online tools:
๐งช Testing
# Run all tests composer test # Run with coverage composer test:coverage # Code style check composer cs-check # Fix code style composer cs-fix # Static analysis composer analyze # All quality checks composer quality
๐ค Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure all quality checks pass (
composer quality) - Submit a pull request
๐ License
MIT License. See LICENSE for details.
๐ Related Packages
This package is part of the MethorZ HTTP middleware ecosystem:
| Package | Description |
|---|---|
| methorz/http-dto | Automatic HTTP โ DTO conversion with validation |
| methorz/http-problem-details | RFC 7807 error handling middleware |
| methorz/http-cache-middleware | HTTP caching with ETag support |
| methorz/http-request-logger | Structured logging with request tracking |
| methorz/openapi-generator | Automatic OpenAPI spec generation (this package) |
These packages work together seamlessly in PSR-15 applications.
๐ Acknowledgments
Built with:
๐ Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
๐ Links
Made with โค๏ธ by Thorsten Merz