fusonic/api-documentation-bundle
A Symfony bundle by Fusonic that generates API documentation directly from your application's routes and controllers, helping teams keep reference docs in sync with the codebase and expose them to developers with minimal configuration.
This is a Symfony bundle, not a Laravel package. Before anything else: composer require fusonic/api-documentation-bundle will pull Symfony components into your Laravel app and give you no service provider — Laravel's package discovery will not register it, and the bundle expects the Symfony kernel. For a pure Laravel app the practical move is to treat this repository as a reference implementation for API-documentation conventions rather than something you install. If you genuinely have a Symfony service in the same stack (e.g., a shared API gateway or a legacy Symfony app alongside Laravel), install it there.
Minimal setup in the Symfony context it targets:
composer require fusonic/api-documentation-bundle
// config/bundles.php
Fusonic\ApiDocumentationBundle\ApiDocumentationBundle::class => ['all' => true],
It layers on top of NelmioApiDocBundle, so Nelmio must also be installed and configured (config/routes/nelmio_api_doc.yaml plus nelmio_api_doc.yaml). First place to look after install is the bundle's DependencyInjection/ directory and its README examples — that tells you which Nelmio areas (annotations/attributes, areas, schema models) this bundle actually decorates, versus what Nelmio already does for free.
First use case: you have a JSON API consumed by a frontend or third party, and you want OpenAPI docs generated from controller attributes/DTOs instead of hand-maintained YAML. Register the doc route, annotate one controller action, hit /api/doc, and confirm the schema appears. If that loop works, the rest of the bundle is incremental.
Laravel equivalent to reach for instead: dedoc/scramble (zero-config, attribute-friendly), knuckleswtf/scribe (human-readable + Postman), or l5-swagger + darkaonline/l5-swagger if you're annotating with zircote/swagger-php. Scramble is the closest philosophical match to this bundle's "generate from your code" approach.
Attribute-driven controller docs (Symfony). The bundle's value is standardizing how Nelmio annotations are applied across a team. Typical pattern: describe the operation and expected response per action, then let the model/response classes supply the schema.
#[Route('/api/users/{id}', methods: ['GET'])]
#[OA\Response(response: 200, description: 'User found', content: new OA\JsonContent(ref: '#/components/schemas/User'))]
public function show(int $id): JsonResponse { /* … */ }
DTO-as-schema. Rather than duplicating field lists in annotations, define the request/response DTOs and reference them. In Laravel with Scramble this is automatic from FormRequests + API Resources; with swagger-php you annotate the DTO class once with #[OA\Schema] and reuse the $ref. This is the single highest-leverage pattern in the repo — steal the shape of it even if you don't run the code.
Per-area configuration. Nelmio's "areas" concept (e.g. internal vs public API) is how you keep internal endpoints out of the customer-facing doc. Mirror this in Laravel by generating two doc artifacts — Scramble supports route filtering via config; Scribe supports groups. Expose only the public one outside the VPN.
CI contract check. Generate the OpenAPI JSON in CI (bin/console nelmio:apidoc:dump in Symfony; php artisan scramble:export or scribe:generate in Laravel), commit or diff it, and fail the build on unexpected changes. This turns documentation drift into a reviewable PR instead of a stale wiki.
Consume the spec, don't just render it. A committed openapi.json feeds typed API clients (openapi-generator, orval, kubb), Postman collections, and contract tests. That downstream tooling is where the real day-to-day return comes from — the HTML doc page is the least valuable artifact.
Integration with existing validation. In Laravel, generate schemas from the same rules you validate with (FormRequest rules()), so docs and behavior can't diverge. This bundle does the Symfony-analogous thing via annotations/serializer metadata; if you hand-write schemas you've re-created the drift problem.
ServiceProvider, no config/*.php publish, no facade. Any tutorial you find for this package assumes bin/console, Symfony Flex, and config/bundles.php. Don't try to shoehorn it in; map the concept.composer.json constraints before upgrading either.bin/console cache:clear first, always. The Laravel analog is php artisan route:clear && php artisan config:clear && php artisan optimize:clear before blaming Scramble/Scribe config.#[OA\...]) and not just Doctrine annotations — older Nelmio-era bundles often silently ignore attributes and produce an empty schema.debug:router / route:list) to catch omissions.GeneratorExtending hooks or Scribe's strategies to add team conventions (standard error envelope, pagination shape) in one place instead of per-endpoint annotations.How can I help you explore Laravel packages today?