Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Api Doc Bundle Laravel Package

tireconnect/api-doc-bundle

A Symfony bundle for generating API documentation from your application's routes and controllers, exposing a browsable reference and OpenAPI spec with minimal setup. Useful for teams documenting REST APIs directly alongside their code.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a fork of NelmioApiDocBundle maintained by Tireconnect, not the upstream project. Before writing a single annotation, confirm which generation you actually have — the fork's package name (api-doc-bundle) suggests the older annotation-driven @ApiDoc style, but verify against the vendor directory rather than assuming:

composer require tireconnect/api-doc-bundle
ls vendor/tireconnect/api-doc-bundle/Resources/config/
  • If you see routing.yml and Annotation/ApiDoc.php → you're on the 2.x-style generation (@ApiDoc, @ApiDoc\Parameters). Use the NelmioApiDocBundle v2.x readthedocs, not the current docs.
  • If you see routing/swaggerui.xml → it's the 3.x/4.x-style generation (swagger-php, @SWG\ or @OA\ objects, nelmio_api_doc.documentation config block).

Minimal setup for the 2.x-style case (adjust if the above told you otherwise):

// app/AppKernel.php
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
# app/config/routing.yml
nelmio_api_doc:
    resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
    prefix:   /api/doc
# app/config/config.yml
nelmio_api_doc:
    name: "Acme API"
    sandbox:
        enabled: true
    swagger:
        api_version: "1.0.0"
        info:
            title: "Acme API"

Then annotate one action and hit /api/doc:

use Nelmio\ApiDocBundle\Annotation\ApiDoc;

/**
 * @ApiDoc(
 *     resource=true,
 *     section="Users",
 *     description="Fetch a single user",
 *     statusCodes={200="OK", 404="Not found"},
 *     requirements={"id"="\d+"}
 * )
 */
public function getUserAction($id) { /* ... */ }

Where to look first, in order: the fork's own Resources/doc/ (it may have diverged from upstream), DependencyInjection/Configuration.php (the authoritative list of config keys for this fork), the bundle's routing files, and finally the upstream NelmioApiDocBundle docs at the version matching whatever is in composer.lock. Do not read the current upstream README — it documents a different API surface.

Implementation Patterns

Annotate the controller, not the entity. The bundle reads controller annotations via a Symfony request listener during the docs route. Every documented endpoint is an annotation on an action; keep them next to the code they describe so they move in the same PR.

Two complementary layers. @ApiDoc describes the operation (description, status codes, whether it's a resource, which section it lives in). The request/response shapes come from either input/output form types and classes, or from sibling swagger-php annotations. In practice the most maintainable split is:

  • @ApiDoc for the human-readable blurb and HTTP semantics
  • input/output pointing at a FormType or DTO with JMS/Serializer metadata for the machine-readable schema
/**
 * @ApiDoc(
 *     resource=true,
 *     section="Users",
 *     input="Acme\UserBundle\Form\CreateUserType",
 *     output="Acme\UserBundle\Model\User",
 *     statusCodes={201="Created", 400="Validation failure"}
 * )
 */

This gets you a form-type-driven schema without duplicating every field by hand. It's the highest-leverage pattern in the bundle and the one most teams skip.

Sections as your navigation. section="Users" groups endpoints in the sidebar. Adopt a fixed vocabulary early (Users, Orders, Admin, …) and enforce it in code review — free-form sections rot into a long tail of one-off groups.

Filter with views for internal-only endpoints. @ApiDoc(views={"public", "internal"}) combined with the route's view parameter produces separate documentation per audience. Useful for a partner-facing doc that omits admin endpoints.

Multiple doc areas. If you have a public and internal API on one Symfony app, define two areas with separate route imports and prefixes, each with its own set of views. This is cleaner than one giant doc with a filter dropdown.

CI gate. The docs endpoint is just an HTTP route, so treat it like one:

// functional test
$client->request('GET', '/api/doc.json');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$doc = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('/api/users/{id}', $doc['paths']);

Optionally validate the dump against a JSON Schema or paste it into Swagger Editor in a nightly job. A stale docs build is worse than no docs, and this is the cheapest way to catch it.

Dump to static. The JSON/YAML routes (/api/doc.json, /api/doc.yaml) let you generate static HTML at build time and ship it to a CDN or commit it to a docs site, rather than exposing the Symfony route in production.

Gotchas and Tips

This is a fork with zero stars, zero dependents, and its last release was 2019-07-03. That has concrete consequences: no upstream security patches flow to you, and nobody has hit your bug before. Pin it exactly ("tireconnect/api-doc-bundle": "1.2.*" or better, a commit hash), commit composer.lock, and treat any upgrade as a manual review.

Keep a diff against upstream. The whole value of a fork is a small diff. Find the upstream version it was cut from (check composer.json, CHANGELOG, or git history), and periodically diff the fork's source against that tag. If the fork only changed a namespace or a template, you can cherry-pick upstream fixes yourself — which is the only maintenance path available to you.

Version lock-in is the real risk. A 2019 bundle means PHP 7.x and Symfony 3.4/4.x. It will not run on Symfony 5+/PHP 8+ without work. Budget for replacing it with upstream NelmioApiDocBundle or nelmio/api-doc-bundle before or during your next framework upgrade; do not let this fork become the reason you can't upgrade PHP.

@ApiDoc does not exist in modern upstream. Search results and Stack Overflow answers for "NelmioApiDocBundle" will overwhelmingly describe @OA\ / @Model / nelmio_api_doc.documentation config. Following those gives you silent no-ops, not errors. Always cross-check your Symfony version and the vendor source before copying a snippet.

Annotation caching bites loudly. After editing annotations you often need bin/console cache:clear — the docs are compiled during the request and a warmed prod cache will serve stale output. If an endpoint silently vanishes from the docs, clear cache first, then check that the controller is actually routed and not excluded.

401/403 on /api/doc. The docs route lives outside your API firewall by default but not always. If the sandbox loads blank, check security.yml access control for the doc prefix; also check that the route prefix in your routing.yml doesn't collide with an API catch-all.

Sandbox auth needs explicit config. The "Try it out" panel doesn't inherit your browser cookies or your app's auth. Configure it:

nelmio_api_doc:
    sandbox:
        authentication:
            name: Authorization
            delivery: header
            default: "Bearer "

Otherwise every sandbox request is a 401 and users conclude the docs are broken.

Debug from the JSON, not the HTML. The HTML UI is a JS app over /api/doc.json; when the page misbehaves, fetch the JSON directly. Every mystery ("why is this parameter missing", "why is this the wrong type") resolves faster in raw JSON than in the rendered page.

input/output must be resolvable. A typo'd class name in @ApiDoc(input="...") typically yields a missing schema rather than an exception, so the docs still render — just wrong. Grep your annotations for class strings and sanity-check them, or add a test asserting the expected properties appear in the JSON.

Extension points worth knowing: custom formatters (Nelmio\ApiDocBundle\Formatter\*) if you need a non-Swagger output, and the annotation handler chain if you need to teach it a new annotation. Both are internal, undocumented-ish APIs — subclassing them makes upgrading harder, so prefer configuration and input/output indirection first.

Prefer the framework-native path over the fork when you can. If the fork's only real delta is a namespace and a couple of templates, and you're still on Symfony 3.4/4.x, using the matching upstream release may cost you less over the next two years — with the caveat that you lose whatever Tireconnect-specific behavior motivated the fork in the first place. Worth a 30-minute diff before you commit to it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings