devizzent/cebe-php-openapi
Fork of cebe/php-openapi providing PHP objects to read/write OpenAPI 3.0/3.1 YAML and JSON. Includes a CLI tool to validate and convert API description files. Install via Composer; works on PHP 7.1+ (including PHP 8).
## Getting Started
### Minimal Setup
1. **Installation**
```bash
composer require devizzent/cebe-php-openapi
The package now supports Symfony YAML 8.x natively, eliminating the need for manual symfony/yaml installation unless handling complex YAML edge cases.
First Use Case: Reading an OpenAPI File
use Cebe\OpenApi\Reader;
use Cebe\OpenApi\OpenApi;
$reader = new Reader();
$openApi = $reader->read('path/to/openapi.yaml'); // or JSON
// Access parsed data
$info = $openApi->getInfo();
echo $info->getTitle();
Where to Look First
tests/ now reflect YAML 8 compatibility.Cebe\OpenApi\Reader, Cebe\OpenApi\Writer, and Cebe\OpenApi\Objects\*.Reading and Validating OpenAPI Specs
$reader = new Reader();
$openApi = $reader->read('api-spec.yaml');
$reader->resolve($openApi); // Strict validation
Generating PHP Objects from OpenAPI
$paths = $openApi->getPaths();
foreach ($paths as $path => $pathItem) {
foreach ($pathItem->getOperations() as $method => $operation) {
echo "Endpoint: {$method} {$path}\n";
echo "Summary: {$operation->getSummary()}\n";
}
}
Writing OpenAPI Files
$openApi = new OpenApi();
$openApi->info = (new \Cebe\OpenApi\Objects\Info())
->title('My API')
->version('1.0.0');
$writer = new \Cebe\OpenApi\Writer();
file_put_contents('output.yaml', $writer->write($openApi));
Integration with Laravel
Reader to the container (unchanged):
$this->app->bind(Reader::class, function () {
return new Reader();
});
Dynamic API Documentation
Route::get('/api/docs', function () {
$openApi = app(Reader::class)->read(storage_path('api-spec.yaml'));
return response()->json($openApi->toArray());
});
Symfony YAML 8 Compatibility
symfony/yaml installation is no longer required for basic YAML parsing.symfony/yaml for advanced use:
composer require symfony/yaml
Validation Strictness
resolve() remains strict. Use flags for flexibility:
$reader->read('spec.yaml', [
'resolve' => true,
'allow_outside_references' => true,
'format_output_for_humans' => true, // Human-readable errors
]);
Circular References
resolve_circular_refs:
$reader->read('spec.yaml', ['resolve_circular_refs' => true]);
Performance
OpenApi objects to avoid reprocessing:
$openApi = Cache::remember('openapi_spec', now()->addHours(1), function () {
return app(Reader::class)->read('spec.yaml');
});
Leveraging Symfony YAML 8
Extending the Library
Reader for custom validation (unchanged):
class CustomReader extends Reader {
protected function customValidation(OpenApi $openApi) {
// Add logic here
}
}
Schema Validation
Objects\Validator to validate requests against OpenAPI schemas:
$schema = $openApi->getComponents()->getSchemas()['User'];
$validator = new \Cebe\OpenApi\Objects\Validator();
$isValid = $validator->validate($request->all(), $schema);
Dynamic Laravel Validation Rules
function generateRulesFromSchema(\Cebe\OpenApi\Objects\Schema $schema): array {
$rules = [];
foreach ($schema->getProperties() as $name => $propertySchema) {
$rules[$name] = 'required';
if ($propertySchema->getType() === 'string') {
$rules[$name] .= '|string';
if ($propertySchema->getFormat() === 'email') {
$rules[$name] .= '|email';
}
}
}
return $rules;
}
Testing
Reader in tests (unchanged):
$mockReader = Mockery::mock(Reader::class);
$mockReader->shouldReceive('read')->andReturn($mockOpenApi);
$this->app->instance(Reader::class, $mockReader);
Deprecated Dependencies
Cebe\OpenApi\* classes for core usage.YAML Best Practices
#, !) to avoid YAML quirks, even with Symfony YAML 8 support.&id *) for complex specs to reduce reference bloat.
NO_UPDATE_NEEDED would **not** apply here—this release introduces meaningful changes (Symfony YAML 8 compatibility and dependency cleanup) that warrant updates to the **Gotchas and Tips** section.
How can I help you explore Laravel packages today?