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

Swagger Bundle Laravel Package

timeinc/swagger-bundle

A Symfony bundle that generates Swagger/OpenAPI documentation for your REST API from PHP annotations, keeping interactive specifications in sync with your code and making it easy to expose and maintain API docs alongside your application.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install: composer require timeinc/swagger-bundle — this pulls in zircote/swagger-php (check which major version it resolves; the bundle's annotations style depends on it).

  2. Register the bundle: classic Symfony apps add new TimeInc\SwaggerBundle\TimeIncSwaggerBundle() to AppKernel.php; Flex apps need the entry in config/bundles.php.

  3. Configure scan paths and output in config.yml/config/packages/timeinc_swagger.yaml. The key shape looks roughly like:

    timeinc_swagger:
        output: "%kernel.project_dir%/web/swagger.json"
        scan:
            - "%kernel.project_dir%/src"
    

    Confirm exact key names against the README — this is the first thing to check, since the bundle is thin and the config is where almost all behavior lives.

  4. First use case: add a single docblock to one controller action:

    /**
     * @SWG\Get(
     *   path="/api/health",
     *   @SWG\Response(response=200, description="OK")
     * )
     */
    public function healthAction() {}
    

    Then run the bundle's console command (typically bin/console swagger:generate — run bin/console list to confirm the exact name) and open the generated JSON. If you get a valid swagger: "2.0" document with your path, the wiring is correct.

Where to look first, in order: the README's config example → Command/ directory for the command name and options → the bundle's DependencyInjection/Configuration.php for authoritative config keys.

Implementation Patterns

Centralize the root document. Put @SWG\Info, @SWG\SecurityDefinitions, and global @SWG\Tag declarations in one dedicated file (e.g. src/Swagger/ApiDoc.php) that contains no logic. swagger-php scans every file in the configured paths, so this becomes your single source of truth for version, title, host, basePath, and auth schemes.

Annotate at the controller/action level, not the entity. The idiomatic pattern is one @SWG\Get/@SWG\Post block per action referencing a shared @SWG\Schema definition via $ref. Keep request/response schemas in a Schemas/ folder of annotation-only classes so the scan set stays predictable.

Generate in CI, not at request time. Treat the generated swagger.json as a build artifact: run the generator as a Composer script ("swagger": "bin/console swagger:generate"), fail the build if it errors, and commit or publish the output. This catches annotation drift before deploy and keeps the runtime free of reflection overhead.

Serve the file separately. The bundle's job is generation; serving is usually simplest via a static file in public/ or a tiny controller that readfile()s it. Pair with Swagger UI (a separate swagger-ui bundle, an nginx location, or Docker image) pointed at the JSON URL — don't try to make the bundle serve UI for you.

Environment-scoped config. Scan src/ in all environments, but point output at a build directory in CI and at public/swagger.json locally. Use %kernel.project_dir% in paths so the config is portable across machines and containers.

Version the spec alongside the API. Tie @SWG\Info(version=...) to a value you can bump with each release tag; combined with the CI-generated artifact, you get a reviewable spec diff per release.

Compose with existing routers cautiously. If you already expose API routes under a prefix, use basePath and host in the @SWG\Info annotation (or config) rather than duplicating the prefix in every path=.

Gotchas and Tips

  • Absolute scan paths only. Relative paths resolve against the CWD, which differs between CLI and web runs. Always wrap in %kernel.project_dir%.
  • Annotation autoloading. swagger-php reads docblocks via doctrine/annotations-style parsing; a missing use Swagger\Annotations as SWG; at the top of a controller silently drops @SWG\* tags (they parse as @SWG\Get with no valid class). A "successful" run producing an empty paths object is almost always a missing use statement or a typo in the alias.
  • @SWG\Info is mandatory. Without it, generation fails validation with an unhelpful error. If you see validation failures on a fresh install, add the ApiDoc.php file first before debugging anything else.
  • Output directory must exist and be writable. The bundle typically writes with file_put_contents; a missing public/ subdirectory or wrong permissions gives a generic write error rather than a path error.
  • Annotation dialect mismatch. The bundle wraps a specific swagger-php major version. swagger-php v3 switched to PHP 8 attributes and OpenApi\Annotations; if you upgrade swagger-php independently, the bundle's annotations (Swagger\Annotations) will stop resolving. Pin swagger-php via Composer if you can't upgrade the bundle too.
  • Operation IDs must be unique. Two actions with the same @SWG\Operation(operationId="getUser") produce invalid client SDKs later even though the JSON generates fine. Let swagger-php derive them, or set them explicitly and lint for duplicates in CI (jq over paths[][].operationId | sort | uniq -d).
  • Debugging generation: run the command with -v to see which files were scanned; a common surprise is that vendor/ or a tests/ fixture contains docblocks that pollute the spec. Narrow scan to src/ only.
  • Cache is a red herring. The generator reads PHP source directly, so cache:clear is not required after editing annotations — but it is required if you changed the bundle's YAML config. Don't waste time clearing cache for annotation changes.
  • Merge semantics on shared paths. Two @SWG\Get annotations on the same path will emit duplicate keys; the last one wins silently. Use @SWG\Path in a single docblock when multiple methods share a path.
  • Extension points are thin. This bundle is a Symfony wrapper around swagger-php; for custom behavior (custom processors, security scheme logic, post-processing the JSON) hook into swagger-php's Generator::UNDEFINED/processor API directly rather than expecting the bundle to expose it. Consider forking the bundle's command if you need extra CLI flags.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
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