infyomlabs/swagger-generator
Generate Swagger/OpenAPI documentation for Laravel APIs directly from your routes and controllers. InfyomLabs Swagger Generator automates spec creation, reduces manual annotation work, and helps keep interactive API docs in sync with your codebase.
Confirm the version gates before anything else. The last release is v3.2.0 (April 2023) and its only noted change is Laravel 10 support. That means: PHP 8.1+, Laravel 10, and no forward claim for Laravel 11/12. If you're on a newer major, treat this as unverified and check the composer.json constraint in the tag before you commit to it — installing with --ignore-platform-reqs to force it in is how you end up debugging a broken generator at the wrong moment.
composer require infyomlabs/swagger-generator
php artisan vendor:publish --provider="InfyOm\SwaggerGenerator\SwaggerGeneratorServiceProvider"
First three places to look:
swagger.json, the basePath, the API prefix, and the security definitions live. Everything else in the package defers to it.boot() — it registers the generation command, the docs route, and the asset publishing. The route it registers tells you exactly where the Swagger UI will be served; the command signature tells you how to regenerate the spec.First use case — one resource, one screenshot. Pick a single controller with standard resource routes (index, store, show, update, destroy), run the generator, and open the docs route in a browser. That gives you three data points immediately: which routes were picked up, what the inferred request/response schemas look like for that model, and whether the UI is loading swagger.json from the URL you expect. Do this before you point the tool at forty controllers — the failure mode of this package is silent under-generation, not an error.
If you scaffolded the controller with InfyOm Laravel Generator, you're the target audience: the conventions the swagger generator assumes (route names, controller method signatures, model casts/docblocks) are the conventions that tool already emits. Regenerate docs as the final step of your scaffolding workflow.
Treat the generated spec as a build artifact, not source. The package infers the spec from routes and models, so swagger.json is a derived file. Decide up front which of two modes you're in:
Mixing the two is the common mistake: a committed file that CI also regenerates produces noisy diffs and stale copies whenever someone forgets to regenerate locally.
Drive it with conventions, and audit the conventions. Because there are no annotation blocks, the quality of the output is a function of how disciplined your code is. Before trusting the generated docs, verify:
{user}, not {id} on a bound model) — mismatches produce path parameters that don't match what a client must send.@property docblocks or casts, since that's what the generator has to work with for schema inference.If a controller doesn't render cleanly, the fastest fix is usually to bring it closer to generated Laravel shape, not to fight the generator.
Group and version APIs with route prefixes, not with separate invocations. If you have /api/v1/... and /api/v2/..., express both as route groups with distinct prefixes and let one generator run cover them, then set basePath/servers in config so Swagger UI's "try it out" hits the right host. Running the generator twice with different filters and merging JSON by hand is a road that ends in duplicate operation IDs.
Chain generation into the workflow you already have. The InfyOm Generator workflow is scaffold → migrate → docs. Add a post-generate step (a small artisan command or a Makefile target) that runs the swagger generator after scaffolding, so a freshly generated CRUD endpoint is documented and browseable without a manual step. For local development, put it in your composer dev script or Watch loop so docs never lag the code.
Add security definitions once, and align them with middleware. Bearer-token auth (Sanctum/Passport) belongs in the config's security scheme block; the Swagger UI "Authorize" button then sets the header for every request. Keep this in sync with what your routes actually require — the generator reads routes but the security block is declarative, and a stale definition produces a UI that either doesn't send tokens or sends them to endpoints that expect basic auth.
Post-process rather than fork. If the inferred schema is 80% right, the right lever is a small JSON post-processor that runs after generation: add examples, tighten response schemas returned by API Resources/transformers (the generator can't see inside them), and inject descriptions. This keeps the upgrade path clean — an override file survives a package major bump, a patched vendor file doesn't.
Validate the output in CI. Run the generated swagger.json through an OpenAPI validator (spectral, swagger-cli validate, or similar) as a non-blocking check to start, blocking once the noise is cleaned up. This catches the realistic regressions: a route renamed but a parameter left behind, duplicate operation IDs from a copy-pasted controller, malformed responses blocks. A snapshot test of the generated JSON is also cheap and catches unintended drift between releases.
Keep the docs honest about response shapes. This package reads controllers and models — it does not introspect your API Resources, form requests, or exception handler. Any endpoint whose request body is defined by a FormRequest and whose response is a transformed resource is the endpoint most likely to be under-specified. Document those explicitly (via post-processing or a hand-maintained overlay) before you hand the URL to a frontend team.
Silent under-generation is the default failure mode. If a route doesn't match the generator's expectations it doesn't warn — it just isn't in the JSON. When an endpoint is "missing" from Swagger UI, don't debug the UI; dump the generated JSON and grep for the operation. The bug is almost always in the route definition, not the viewer.
Laravel 11/12 is unverified, and the release is old. v3.2.0 is a compatibility release for Laravel 10, not a feature release. There's no published support or security policy; the release cadence over the last 12+ months is a data point you should record if you maintain a dependency health register. Pin the version in composer.json and add a regression step to your framework upgrade checklist — the risk isn't that it breaks loudly, it's that it silently generates less.
config:cache and stale artifacts. Two separate traps here. First, the standard one: if the config file reads env() at runtime it will be stale after config:cache; always php artisan config:clear when docs behavior doesn't match .env. Second, the package-specific one: the spec on disk doesn't regenerate itself. If your deploy caches config and serves a committed swagger.json, a route change in the app and no regeneration means docs and reality diverge with no error anywhere.
Asset publishing overwrites the view. vendor:publish without a tag will re-copy the Blade view and the UI assets, clobbering any title/branding/UI-version changes you made. Publish with the specific tag, keep a diff in the PR, and treat the view as a file you own once you've touched it.
Behind a proxy, the docs route loads the wrong spec URL. If the app runs behind a load balancer or in a subdirectory, the Swagger UI page will try to fetch swagger.json from the wrong absolute URL. Check the config's basePath and the view's spec URL, and set TrustProxies correctly — this is a five-minute fix that people lose an hour to because the symptom (empty UI, no console explanation of why) doesn't point at the cause.
Long-running workers (Octane, Horizon). Less acute for a docs generator than for a client, but the published config and any singleton the provider binds are reused across requests. If you've extended the generator with application code, prefer scoped() bindings and reset state in config/octane.php.
Security definitions are declarative, not derived. The generator cannot tell that auth:sanctum is on a route. Every protected endpoint you add needs the security scheme applied in the config or post-processor; nothing about adding middleware will update the spec. Audit this once per release cycle — a docs page that claims anonymous access to a protected endpoint is worse than no docs.
Where to extend, in order of cost: the config (output path, base path, security schemes) → a post-processing step on the JSON → overriding the published Blade view → extending the generator command class in your own service provider. Anything beyond that is a fork, and for a package whose last change was a framework compatibility bump, a fork is a maintenance liability you should price in before starting.
Debugging checklist for "the docs are wrong": dump the JSON and inspect it directly, confirm the route is registered with php artisan route:list, confirm the model's casts/docblocks are what you think they are, then config:clear and regenerate. In that order — the majority of issues are the second or third step, not the fourth.
How can I help you explore Laravel packages today?