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

Laravel Swagger Laravel Package

mtrajano/laravel-swagger

Generate Swagger/OpenAPI documentation for Laravel APIs directly from your routes and controller annotations. mtrajano/laravel-swagger scans your app to produce interactive API docs, reducing manual spec maintenance and keeping endpoints in sync.

Deep Wiki
Context7

Getting Started

Install as a dev dependency so generation stays out of production builds:

composer require --dev mtrajano/laravel-swagger
php artisan vendor:publish --provider="Mtrajano\LaravelSwagger\LaravelSwaggerServiceProvider"

Minimal config/laravel-swagger.php:

return [
    'output' => 'storage/api-docs/api-docs.json',
    'format' => 'json',
    'routes' => [
        'prefix'   => 'api',
        'middleware' => [], // optional narrowing
    ],
    'docs' => [
        'info'    => ['title' => 'My API', 'version' => '1.0.0'],
        'servers' => [['url' => config('app.url') . '/api']],
    ],
];

Generate and inspect:

php artisan laravel-swagger:generate
cat storage/api-docs/api-docs.json | jq '.paths | keys'

Where to look first: the generated file, not the package source. Diff it against reality to see what the scanner picked up. Then open config/laravel-swagger.php — almost everything (route scope, global info, security) is driven from there.

First use case: pick a single controller — typically a read-only GET /api/... index or show — add a @response docblock to the action, regenerate, and import the JSON into Swagger Editor or Postman. Once one endpoint round-trips cleanly, expand controller by controller.

Implementation Patterns

Convention-driven generation. The package walks routes matching the configured prefix/middleware, resolves controller actions, and derives path parameters, request bodies (from FormRequest rules), and responses (from docblocks). Your leverage comes from keeping code consistent so the conventions hold.

Document via controller docblocks. Put a summary/description and typed response examples above each action:

/**
 * List users
 *
 * Returns a paginated list of users.
 *
 * @response 200 {
 *   "data": [{"id": 1, "name": "Jane"}],
 *   "meta": {"current_page": 1}
 * }
 */
public function index() { ... }

For large payloads prefer @responseFile 200 tests/Responses/users_index.json — inline JSON is fragile and bloats controllers.

Lean on FormRequest for bodies. A StoreUserRequest with scalar rules (required|string|max:255, email, integer, boolean, array, in:...) maps cleanly to a request schema. Keep the rules() method declarative; push custom logic into withValidator/after so it doesn't confuse inference.

Tag by controller. Add a class-level or first-method @tags/summary so endpoints group sensibly in the UI. Consistent tags make the spec usable as an onboarding doc rather than a dump.

Scope with route filters per audience. For a public/partner/internal split, invoke generation multiple times with different --routes / --except combinations and distinct --output files rather than trying to express everything in one config.

Auth schemes in config, referenced in code. Define securityDefinitions (Bearer, ApiKey) in the docs block, then annotate controllers that require it. This is the only clean way to get the "Authorize" button working in Swagger UI.

CI workflow. Regenerate on every PR that touches routes/controllers, validate with swagger-cli validate storage/api-docs/api-docs.json, and either commit the artifact or publish it as a build artifact consumed by your docs site. A failing validation is a cheap guard against broken annotations landing on main.

Preview locally. Point any Swagger UI instance (Docker swaggerapi/swagger-ui, the hosted editor, or a tiny Blade page) at the generated file. Don't rely on editing the JSON by hand — regenerate.

Gotchas and Tips

  • Package age is the biggest risk. Last release was late 2020; expect friction on PHP 8.1+/Laravel 9+. Pin the package, run the install in a throwaway branch first, and if composer blocks you, either fork and loosen constraints or evaluate dedoc/scramble/knuckleswtf/scribe for greenfield work.
  • Swagger 2.0, not OpenAPI 3. Specs are 2.0-shaped; modern tooling (some generators, newer SDK toolchains) will complain. Know this before promising OpenAPI 3 output to a consumer.
  • Silent route omission. A route that doesn't match the configured prefix/middleware/filter simply won't appear. When an endpoint is missing, debug the filter config first — not the docblock. Verbose output (-v) on the artisan command usually reveals the scanned route list.
  • Inline @response JSON is brittle. A trailing comma, unescaped quote, or multiline array breaks parsing or produces garbage. Use @responseFile for anything beyond trivial payloads, and validate the generated JSON in CI.
  • FormRequest inference is literal. Custom Rule objects, conditional arrays (required_if, exclude_if), regex rules, and file uploads are frequently under- or mis-described. Treat inferred schemas as a starting point and hand-annotate where accuracy matters (uploads, unions, polymorphic bodies).
  • Query parameters aren't inferred from request()->validate() inside controllers. Declare them explicitly or move the validation into a FormRequest and verify the generated parameter location.
  • Route model binding types are weakly inferred. /users/{user} without a typed parameter often lands as a string; add a typed signature or an explicit annotation to get integer.
  • --append is stateful. Appending to an existing spec keeps stale paths around after route renames/deletes. Prefer a clean regenerate unless you have a specific multi-source merge reason.
  • Responses vs. reality. API Resources/JsonResource collections, pagination wrappers, and transformers are invisible to the scanner. Document those shapes explicitly or your consumers will build against the wrong contract.
  • Don't hand-edit the output. It's regenerated wholesale; any manual fix in the JSON is lost on the next run. Changes belong in docblocks or config.
  • Extension points are config-only. Global info, servers, securityDefinitions, and route filters are supported; per-endpoint customisation happens through docblock annotations. If you need more, patch/fork rather than trying to coerce config.
  • Commit vs. ignore. If downstream tooling (Postman, SDK generation, a docs site) fetches the file, commit it and treat it as a reviewed artifact. Otherwise generate in CI and publish — leaving a stale committed spec is worse than none.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager