nelmiopros/api-doc-bundle
A Symfony/PHP bundle that generates interactive API documentation from your controllers, routes, and annotations. It provides a browsable web UI and machine-readable specs, making it easier to explore, test, and maintain your API endpoints.
First, the honest caveat: nelmiopros/api-doc-bundle is a fork of nelmio/NelmioApiDocBundle, which is a Symfony bundle — not a Laravel package. It has zero stars and zero dependents, and it wires itself into Symfony's kernel via Bundle registration, DI container, and Symfony routing. You cannot composer require it into a Laravel app and expect it to boot.
If you landed here because you searched for "generate API docs from annotations" as a Laravel dev, do not start with this package. Start with one of these instead:
knuckleswtf/scribe — generates OpenAPI + human-readable docs by introspecting Laravel routes, FormRequests, and controller docblocks. Closest conceptual match.dedoc/scramble — zero-annotation OpenAPI generation from Laravel route signatures and typed requests. Best DX if you don't want to annotate anything.darkaonline/l5-swagger — bundles zircote/swagger-php (the same annotation parser Nelmio sits on top of) and exposes Swagger UI. This is the package you want if you specifically want attribute/annotation-driven docs in Laravel.If you are actually evaluating this fork (e.g. maintaining a mixed Symfony/Laravel shop, or auditing a fork for upstream drift), the minimal steps in a Symfony app are:
composer require nelmio/api-doc-bundle
Register the bundle in config/bundles.php:
return [
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true],
];
Import the routing in config/routes/nelmio_api_doc.yaml:
nelmio_api_doc:
resource: '@NelmioApiDocBundle/config/routing/swaggerui.xml'
prefix: /api/doc
Then annotate your first controller with OpenAPI attributes (zircote/swagger-php provides the #[OA\...] classes; Nelmio adds #[Model], #[Areas], etc. on top):
use OpenApi\Attributes as OA;
#[OA\Get(
path: '/api/users/{id}',
summary: 'Fetch a user',
tags: ['Users'],
parameters: [new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer'))],
responses: [new OA\Response(response: 200, description: 'OK')]
)]
public function show(int $id) { /* ... */ }
Visit /api/doc and you should get Swagger UI. First real use case: documenting the response shape of a resource endpoint by pointing #[Model] at a DTO — this is where Nelmio's value over raw swagger-php lives, because it reads your serializer metadata to infer the schema for you.
Symfony-side workflows (what this package actually does):
#[OA\Schema] on DTOs, #[OA\Get]/#[OA\Post] on controller actions, #[OA\Response] for status mapping. Keep one #[OA\Info] at the top of a base controller or docs/ class.#[Model] for serializer inference. Point #[Model(type: UserOutput::class, groups: ['api'])] at a DTO and Nelmio derives the response schema from your Symfony Serializer groups. This is the feature that saves the most time — you stop hand-writing $refs.#[Areas(['internal'])] on controllers plus an areas: block in config/packages/nelmio_api_doc.yaml lets you ship /api/doc/internal and /api/doc/partner from the same codebase. Useful for public-vs-private APIs.bin/console nelmio:apidoc:dump --format=json in CI and git diff --exit-code the result so undocumented changes break the build. This is the single most effective pattern for keeping docs honest.If you're the Laravel dev translating concepts: the equivalent workflow is l5-swagger + a base_path('app/OpenApi') directory of #[OA\Info], #[OA\Schema], and #[OA\PathItem] annotation classes, with php artisan l5-swagger:generate wired into your deploy script and a git diff check in CI. The mental model (attributes on classes → generated spec → served UI) is identical; only the wiring differs.
Symfony\Component\HttpKernel\Bundle\Bundle, the Symfony routing LoaderInterface, and container compilation passes. The porting effort will exceed the cost of adopting l5-swagger or scramble. If you want annotation-driven docs in Laravel, use darkaonline/l5-swagger — it uses the same zircote/swagger-php attribute classes, so your #[OA\...] code is portable.nelmio/api-doc-bundle upstream. A 0-star, 0-dependent fork is either a personal scratch copy or an abandoned mirror. Check the composer.json version/branch-alias and the CHANGELOG against upstream's latest release. If they match, just depend on the official package.@SWG\..., @ApiDoc) were removed in favor of PHP 8 attributes. Any tutorial older than ~2022 will be wrong. If you're migrating, expect to touch every annotated controller.swagger-php is a transitive dependency, not bundled. You install zircote/swagger-php alongside, and its version determines which #[OA\...] classes exist. Attribute class names shift between major versions — pin it and read its changelog, not just Nelmio's, when debugging "class not found" on OA\*.nelmio_api_doc.yaml (documentation.ui). For CI diffs and client generation, always use the raw JSON endpoint (/api/doc.json or nelmio:apidoc:dump --format=json), never scrape the HTML.bin/console cache:clear before opening GitHub issues against your annotations. In prod, warm it at deploy time.#[Model(groups: [...])] must exactly match a group applied on your DTO properties, or Nelmio silently emits an empty object schema. Validate by dumping the JSON spec, not by eyeballing Swagger UI.Nelmio\ApiDocBundle\Describer\DescriberInterface and Nelmio\ApiDocBundle\ModelDescriber\ModelDescriberInterface are the seams to implement for a custom framework bridge. In practice, though — use l5-swagger and save yourself the week.How can I help you explore Laravel packages today?