ez-php / openapi
OpenAPI 3.x spec generator for the ez-php framework — PHP attributes on controllers, reflection-based spec building, GET /openapi.json endpoint
Requires
- php: ^8.5
- ez-php/contracts: ^2.0
- ez-php/http: ^2.0
Requires (Dev)
- ez-php/docker: ^2.0
- ez-php/framework: ^2.0
- ez-php/json-schema: ^2.0
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^13.0
Suggests
- ez-php/json-schema: Needed for openapi.schema_classes (auto-generated components.schemas)
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 2.5.6
- 2.5.5
- 2.5.4
- 2.5.3
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.11
- 2.4.10
- 2.4.9
- 2.4.8
- 2.4.7
- 2.4.6
- 2.4.5
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.9
- 2.3.8
- 2.3.7
- 2.3.6
- 2.3.5
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- 1.14.0
- 1.13.1
- 1.13.0
- 1.12.2
- 1.12.1
- 1.12.0
- 1.11.2
- 1.11.1
- 1.11.0
- 1.10.0
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.0
- 1.7.1
- 1.7.0
- 1.6.1
- 1.6.0
- 1.5.1
- 1.5.0
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
This package is auto-updated.
Last update: 2026-09-30 19:50:25 UTC
README
OpenAPI 3.0.0 / 3.1.0 spec generator for the ez-php framework. Annotate controller methods with PHP attributes and get a live GET /openapi.json endpoint — no code generation, no annotation parsing framework, no YAML.
Installation
composer require ez-php/openapi
Register the service provider in provider/modules.php:
$app->register(\EzPhp\OpenApi\OpenApiServiceProvider::class);
Usage
Add attributes to your controller methods:
use EzPhp\OpenApi\Attributes\ApiOperation; use EzPhp\OpenApi\Attributes\ApiParam; use EzPhp\OpenApi\Attributes\ApiResponse; final class UserController { #[ApiOperation(summary: 'List users', tags: ['users'])] #[ApiResponse(200, 'List of users')] #[ApiParam('search', 'string', 'query', false, 'Filter by name')] public function index(Request $request): Response { ... } #[ApiOperation(summary: 'Get user')] #[ApiResponse(200, 'The user', UserSchema::class)] #[ApiResponse(404, 'Not found')] #[ApiParam('id', 'integer', 'path', true, 'The user ID')] public function show(Request $request): Response { ... } }
Visit GET /openapi.json to retrieve the generated spec.
Attributes
#[ApiOperation]
| Parameter | Type | Default | Description |
|---|---|---|---|
$summary |
string |
'' |
Short description of the operation |
$description |
string |
'' |
Longer Markdown description |
$tags |
list<string> |
[] |
Tag names for grouping in the UI |
Not repeatable — one per method.
#[ApiResponse]
| Parameter | Type | Default | Description |
|---|---|---|---|
$status |
int |
— | HTTP status code (required) |
$description |
string |
'' |
Human-readable description |
$schemaClass |
?string |
null |
FQCN used to emit a $ref in the response |
Repeatable — multiple responses per method.
#[ApiParam]
| Parameter | Type | Default | Description |
|---|---|---|---|
$name |
string |
— | Parameter name (required) |
$type |
string |
'string' |
JSON Schema type: string, integer, boolean |
$in |
string |
'query' |
Location: path, query, header, cookie |
$required |
bool |
false |
Whether required (path params always required) |
$description |
string |
'' |
Human-readable description |
Repeatable — multiple parameters per method.
Configuration
| Key | Default | Description |
|---|---|---|
app.name |
'API' |
Spec info.title |
app.version |
'1.0.0' |
Spec info.version |
openapi.endpoint |
'/openapi.json' |
URI for the generated spec |
openapi.components |
[] |
Reusable component objects merged into the spec's components key, e.g. ['schemas' => ['User' => ['type' => 'object', ...]]]. Required for #[ApiResponse(schemaClass: ...)] refs to resolve. |
openapi.version |
'3.0' |
3.0 or 3.1. 3.1 uses JSON Schema 2020-12 as emitted by ez-php/json-schema; for 3.0 the component schemas are converted (type arrays → nullable, examples → example, …). |
openapi.schema_classes |
[] |
list<class-string> auto-converted into components.schemas via ez-php/json-schema's SchemaGenerator, keyed by short class name. Requires ez-php/json-schema (a soft dependency — install it separately). |
Auto-generating component schemas
Instead of hand-writing every schema under openapi.components, point openapi.schema_classes
at your DTOs and let ez-php/json-schema derive them from typed properties:
// config/openapi.php return [ 'schema_classes' => [App\Dto\User::class, App\Dto\Post::class], ];
Each class is generated under components.schemas keyed by its short class name (User,
Post) — the same short-name convention #[ApiResponse(schemaClass: ...)]'s $ref already
uses, so the two line up automatically. A schema manually supplied under
openapi.components['schemas'] for the same key always wins over the generated one, so you
can override individual classes without losing auto-generation for the rest.
Notes
- Only
[Controller::class, 'method']handler routes are reflected for attributes. Closure-based routes appear in the spec without attribute data. - Path parameters (
{id}) are auto-detected from route patterns and added asin: 'path', required: true, type: 'string'when not explicitly declared via#[ApiParam]. - Component schemas (
#/components/schemas/...) referenced by$schemaClassresolve against whatever is configured inopenapi.components(hand-written) oropenapi.schema_classes(auto-generated) — this module emits the$refand thecomponentskey it points at, but does not itself introspect your code; population is either manual or delegated toez-php/json-schema.