jlapp/swaggervel
Swaggervel integrates Swagger UI and Swagger-PHP with Laravel, generating interactive API documentation from your annotations and serving it through configurable routes. Publish the config and assets, then browse a ready-made docs UI for your application's API.
Install and register
composer require jlapp/swaggervel
On Laravel 5.5+ auto-discovery wires Jlapp\Swaggervel\SwaggervelServiceProvider for you. On older versions add it to config/app.php's providers array, and optionally alias the Swaggervel facade.
Publish config and UI assets
php artisan vendor:publish --provider="Jlapp\Swaggervel\SwaggervelServiceProvider"
Where to look first: config/swaggervel.php. The keys that matter daily are paths (which directories get scanned for annotations — default app/), doc-route (default api/docs), json-route (default api/docs/json), and swagger-version. Everything else is cosmetic.
First use case — document one endpoint
Add a Swagger annotation block above a controller method:
/**
* @SWG\Get(
* path="/api/users/{id}",
* @SWG\Parameter(name="id", in="path", required=true, type="integer"),
* @SWG\Response(response=200, description="OK")
* )
*/
public function show($id) { ... }
Hit /api/docs — the UI renders, /api/docs/json serves the generated spec. Note the @SWG\ prefix: this package targets swagger-php 2.x and OpenAPI 2.0, not @OA\.
Centralize the API envelope. Put @SWG\Info, @SWG\SecurityScheme, and @SWG\Tag blocks in one place (e.g. app/Http/Controllers/ApiDefinitionController.php) so every endpoint inherits consistent metadata. Controllers stay focused on their own paths.
Use @SWG\Definition for models and $ref everywhere. Define User, Order, etc. once, then reference them:
@SWG\Response(
response=200,
description="User",
@SWG\Schema(ref="#/definitions/User")
)
This keeps spec size down and makes schema changes a one-file edit.
Generate in CI, not per-request. The JSON route regenerates on every hit (expensive with a large paths list). Add an artisan step — swaggervel:generate where available, otherwise hit the JSON route in a warm-up container — and commit or upload the spec. Frontend teams and contract tests consume a stable artifact instead of a live endpoint.
Scope paths aggressively. Set paths to [base_path('app/Http/Controllers/Api')] and exclude generated/vendor code. Smaller scope = faster generation and fewer spurious parse errors.
Gate the UI behind an environment check. The docs route is public by default. Wrap it with a middleware or guard:
if (app()->isProduction() && ! auth()->user()?->isAdmin()) {
abort(404);
}
or serve the built UI from storage and skip the route in prod entirely.
Multiple spec sets — if you have public and internal APIs, run two configs (Laravel 6+ supports multiple config files) or maintain separate paths and doc-route values per environment.
@SWG vs @OA is a hard fork in the road. This package pins swagger-php 2.x. If a teammate copies annotations from an OpenAPI 3 project (@OA\Info), they will be silently ignored. Standardize on @SWG and pin swagger-php in composer.json so a transitive composer update doesn't break parsing./api/docs/json directly and look for missing paths — that is your debug signal. swagger-php's own bin/swagger CLI over the same directory is a good second opinion.config/swaggervel.php or annotations, run php artisan config:clear (and route:clear if you changed doc-route). The docs URL 404ing after a config change is almost always this./api/docs returns a blank page, the assets weren't published or are being served from a path that doc-dir doesn't point at. Re-run vendor:publish.api/docs is a common path other packages claim. Check php artisan route:list | grep docs before blaming Swaggervel.darkaonline/l5-swagger (actively maintained, @OA support) and treat Swaggervel as a maintenance choice for existing apps.resources/views/vendor/swaggervel to brand the UI or add auth headers, and drop a custom swaggervel.php per environment if you need different doc-route values on staging vs. local.How can I help you explore Laravel packages today?