gohiei/api-doc-bundle
gohiei/api-doc-bundle is a PHP package for generating browsable API documentation from your application's routes and annotations. It keeps endpoint references close to the code, making internal or public API docs easier to maintain and share with your team.
The first thing a Laravel developer needs to know: this is a Symfony bundle, not a Laravel package. gohiei/api-doc-bundle is a rename/fork of nelmio/api-doc-bundle — the long-standing Symfony bundle that generates OpenAPI/Swagger documentation from controller annotations. Composer will pull symfony/framework-bundle, symfony/config, the nelmio service wiring, and a 2019-era zircote/swagger-php. It will not boot inside a Laravel application without essentially rebuilding the Symfony container around it, which defeats the purpose.
So "getting started" splits into two paths:
If you are actually in a Symfony app (older 4.x project):
composer require gohiei/api-doc-bundle — pin it, since the last tagged release is 2019-12-30.Gohiei\ApiDocBundle\ApiDocBundle (or whatever namespace the fork uses — inspect vendor/ first, the namespace is the most likely thing to differ from upstream) in config/bundles.php.nelmio_api_doc.yaml in config/routes/ pointing /api/doc at the bundle's controller, and protect the route with a firewall/access_control before exposing anything.nelmio_api_doc.areas, documentation.info).@OA\Get / @OA\Response annotations (from zircote/swagger-php), hit /api/doc, and confirm the Swagger UI renders that single endpoint. Only then scale to the rest of the API.If you are in Laravel (the realistic scenario for this review): do not install it. The Laravel-native equivalents are dedoc/scramble (annotation/reflection-driven, zero-config OpenAPI) or knuckleswtf/scribe (annotation-driven, generates Postman/HTML docs). Both are actively maintained, PHP 8-aware, and integrate with Laravel routing/validation middleware. That is the correct first step.
Since the bundle is only viable in Symfony, the day-to-day patterns below apply to that context — but they also show what you would lose if you tried to port it into Laravel, which is the useful comparison.
Annotate-then-render loop. Each controller action carries OpenAPI annotations; the bundle scans controllers (usually via a configured scan path) and assembles a spec. The "documentation lives next to the handler" pattern is the core value — and it is exactly what Scramble gives you in Laravel without annotations.
Areas for API versioning. nelmio_api_doc.areas lets you declare default and, say, internal, and expose /api/doc/default and /api/doc/internal. Useful for the "public API vs. admin API" split. In Laravel you would model this with route groups plus separate Scramble configurations.
External spec merging. The bundle can consume an existing swagger.yaml via areas.<name>.documentation and merge annotations on top. Handy when part of the API is generated by another service.
Model documentation. @Model annotations (or serializer metadata) map DTOs/entities to schema definitions so response bodies are documented once and reused. In Laravel this role is played by API Resources plus Scramble's inference from validation rules and return types.
Security schemes. A securityDefinitions block plus @Security annotations on actions. Keep the definitions in a shared config file, not scattered across controllers.
CI integration. Dump the spec in CI (bin/console nelmio:apidoc:dump) and diff it in a PR so contract changes are reviewed. This is the one pattern worth stealing verbatim into a Laravel pipeline — Scramble can dump JSON the same way for a git diff gate.
The fork is effectively abandoned. Last release 2019-12-30, zero stars, zero dependents. Upstream nelmio/api-doc-bundle has moved on to attributes, PHP 8.1+, and modern Symfony; this fork has none of that. There is no reason to prefer it over upstream, and a strong reason not to: no security patches, no compatibility fixes, no issue tracker activity worth relying on.
Namespace drift is the first failure mode. Renaming a fork means use Nelmio\ApiDocBundle\... imports in any copied docs/config will break. Grep vendor/gohiei/ for the real namespace before writing a single line of config.
Annotations vs. attributes. 2019-era tooling relies on Doctrine annotations (@OA\...). On any modern PHP/Symfony stack these are either deprecated or unsupported. If your project is on attributes, this bundle simply cannot read your controllers.
Silent empty docs. The most common bug is a spec that renders with zero paths. Causes, in order of likelihood: the scan path in config doesn't match your src/ layout; annotations aren't imported (missing use OpenApi\Annotations as OA;); or the bundle cache is stale. Run cache:clear, then dump the spec to JSON and inspect it directly rather than trusting the UI.
Route ordering and security. The docs route must sit after your firewall definitions in Symfony's security config, or you'll either get a 404 or accidentally publish internal endpoint documentation publicly. Treat /api/doc as a production-exposure decision, not a default.
Annotation scanning is I/O-heavy. Large controllers directories slow down cache warmup. Scope the scan paths narrowly and cache aggressively. In Laravel terms: this is exactly why Scramble's reflection approach (no annotation parsing) is a better fit — it doesn't pay this cost.
The honest recommendation. If you're in Laravel: skip this entirely, use Scramble. If you're on legacy Symfony 4 and already using Nelmio 4.x: use upstream nelmio/api-doc-bundle, not this fork, unless you have a specific pinned reason. The only legitimate reason to touch gohiei/api-doc-bundle is inheriting a project that already locked it — in which case your first task is planning the migration to upstream or to attributes.
How can I help you explore Laravel packages today?