draw/framework-extra-bundle
Symfony bundle that integrates draw/* components with configuration under the draw_framework_extra namespace. Some features auto-enable when components are present; others are opt-in to avoid unnecessary load or side effects. Includes Application and OpenAPI integrations.
Install the Bundle
Add to composer.json:
"require": {
"draw/framework-extra-bundle": "^1.0"
}
Run composer require draw/framework-extra-bundle.
Enable in config/bundles.php
return [
// ...
Draw\FrameworkExtraBundle\FrameworkExtraBundle::class => ['all' => true],
];
Configure Basic OpenAPI
Add minimal config to config/packages/draw_framework_extra.yaml:
draw_open_api:
schema:
info:
title: 'My API'
version: '1.0.0'
First Use Case: Document a Controller
Annotate a controller method with @OpenApi\Operation:
use Draw\Component\OpenApi\Schema\Operation;
class MyController {
#[Operation(operationId: 'getUser', tags: ['Users'])]
public function getUser() {
return ['id' => 1, 'name' => 'John'];
}
}
Define Schema
Extend the base schema in config/packages/draw_framework_extra.yaml:
draw_open_api:
schema:
info:
description: 'API for managing users'
servers:
- url: 'https://api.example.com/v1'
Annotate Controllers
Use @OpenApi\Tag for grouping and @Operation for method-level docs:
#[Tag('Users')]
class UserController {
#[Operation(
operationId: 'createUser',
summary: 'Create a new user',
requestBody: new RequestBody(
required: true,
content: new \stdClass() // Define request body schema
)
)]
public function create(User $user) { ... }
}
Generate Docs Run:
bin/console draw:open-api:generate
Outputs to var/cache/dev/openapi.json.
Enable Response Conversion
draw_open_api:
responseConverter: true
Annotate Responses
Use @Draw\Bundle\OpenApiBundle\Response\Serialization:
#[Serialization(
statusCode: 201,
serializerGroups: ['user:read']
)]
public function create(User $user) { ... }
Inject Query Parameters Enable in config:
draw_open_api:
convertQueryParameterToAttribute: true
Annotate parameters:
public function list(
#[QueryParameter(name: 'page', description: 'Page number')]
int $page = 1
) { ... }
Doctrine Support Auto-detects DoctrineBundle. Enable explicitly if needed:
draw_open_api:
enableDoctrineSupport: true
Definition Aliases Simplify entity references in OpenAPI:
draw_open_api:
definitionAliases:
- { class: App\Entity\User, alias: User }
Event Listeners Extend functionality (e.g., dynamic versioning):
// src/EventListener/VersionListener.php
class VersionListener implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [KernelEvents::VIEW => ['onKernelView', 31]];
}
public function onKernelView(ViewEvent $event) { ... }
}
Configuration Validation
The schema section in config is not validated—ensure it matches OpenAPI format manually.
Doctrine Auto-Detection
enableDoctrineSupport: null auto-detects DoctrineBundle. Set to false explicitly if unused to avoid errors.
Query Parameter Injection
Forgetting to set convertQueryParameterToAttribute: true will prevent parameter injection.
Response Serialization
Without responseConverter: true, annotated responses won’t auto-serialize. Test with:
bin/console debug:container draw_open_api.response_converter
Check Generated Docs
Inspect var/cache/dev/openapi.json for errors or missing annotations.
Clear Cache After config changes, run:
bin/console cache:clear
Log Events
Enable Symfony’s profiler to debug VIEW events for listeners:
# config/packages/dev/framework.yaml
framework:
profiler: { only_exceptions: false }
Custom Extractors
Extend Draw\Component\OpenApi\Extractor\ExtractorInterface to add new metadata sources (e.g., YAML files).
Schema Post-Processing
Use a KernelEvents::VIEW listener to modify the generated schema dynamically:
public function onKernelView(ViewEvent $event) {
$schema = $event->getControllerResult();
// Modify $schema here
}
Sandbox Installation
The draw:open-api:install-sandbox command is WIP—test in a dev environment first:
bin/console draw:open-api:install-sandbox v3.52.5
Use operationId
For codegen compatibility, always specify operationId in @Operation to avoid route-name collisions.
Leverage definitionAliases
Reduce verbosity in schemas by aliasing complex types:
definitionAliases:
- { class: App\Entity\Order\Item, alias: OrderItem }
Composer Scripts
Add to composer.json to auto-install sandbox on assets:install:
"scripts": {
"post-install-cmd": [
"@auto-scripts"
],
"auto-scripts": {
"draw:open-api:install-sandbox": "symfony-cmd"
}
}
How can I help you explore Laravel packages today?