rakutentech/laravel-request-docs
Automatically generate clean, interactive API documentation for your Laravel application directly from your routes, form requests, and API resources—no manual annotations or extra config required. Just install the package and instantly browse every endpoint, parameter, and response.
Laravel Request Docs generates a browsable API documentation UI directly from your routes, FormRequest validation rules, and controller docblocks — no separate spec file to maintain.
composer require rakutentech/laravel-request-docs
php artisan vendor:publish --tag=request-docs-config
Then open /request-docs (the path is controlled by the route key in config/request-docs.php). If you also need the front-end assets published, check php artisan vendor:publish for the package's asset tag — v2 ships compiled assets, so most projects don't need this.
Where to look first
config/request-docs.php — the whole behaviour of the package lives here: enabled, route, middlewares, save_to_disk, ignore_rules, hide_rules, rules, custom, plus presentation keys (header, logo).routes/api.php — this is the source of truth for what appears in the UI.First use case: install it against an existing API, hit /request-docs, and confirm your route list and auth headers render correctly. You'll typically discover within five minutes that the routes look fine but the parameters are thin, because the package infers query/body params from validation rules. Everything after that first look is about feeding it better metadata.
On v2.44: this release is a Laravel 13.x compatibility bump only — no config keys changed, no API changes, no deprecations. If you're planning a Laravel 13 upgrade, this removes request-docs from your blocker list; if you're staying on 11/12, upgrading is a no-op.
Let FormRequests do the heavy lifting. The package reads validation rules to derive parameter names, types, and required-ness. A well-typed FormRequest buys you a mostly-complete request body table for free:
class StoreOrderRequest extends FormRequest
{
public function rules(): array
{
return [
'customer_id' => ['required', 'integer', 'exists:customers,id'],
'items' => ['required', 'array', 'min:1'],
'items.*.sku' => ['required', 'string'],
'items.*.qty' => ['required', 'integer', 'min:1'],
'notes' => ['nullable', 'string', 'max:1000'],
];
}
}
If you inline $request->validate([...]) in the controller instead, you get less reliable output — moving those rules into a FormRequest is the single highest-leverage change for doc quality. Same for StoreOrderRequest subclasses on update endpoints, where sometimes rules show params as optional.
Group and annotate routes in config. The rules block lets you match route patterns and attach group descriptions, shared params, and headers:
'rules' => [
'orders/*' => [
'description' => 'Customer order lifecycle',
'params' => [
'X-Idempotency-Key' => 'required|string',
],
],
],
Use this to give each domain area a readable heading and to document cross-cutting headers (tenant IDs, idempotency keys) once instead of per route.
Annotate responses in the controller docblock. Request docs are largely inferred; responses are not. Use the package's annotations on the controller method to supply the payload shape:
/**
* @LRDparam page required|integer Pagination cursor
* @LRDresponse 200 {"data": [{"id": 1, "status": "paid"}]}
* @LRDresponse 422 {"message": "The given data was invalid."}
*/
public function index(IndexOrdersRequest $request) { ... }
Add overwrite to an annotation when you want it to replace inferred output rather than supplement it.
Hide what shouldn't be public. Three escalating tools:
hide_rules in config for route patterns (internal/admin endpoints).ignore_rules to drop params you don't want surfaced (debug flags, _token).@hideFromAPIDocumentation in a controller docblock to suppress an entire controller.Gate the route in non-local environments. The middlewares key plus enabled is your access control. Never expose /request-docs on a public production host — put it behind your auth/can: middleware, or restrict by IP at the proxy, and toggle enabled via env:
'middlewares' => ['web', 'auth', 'can:viewApiDocs'],
Generate static docs for CI. With save_to_disk enabled and a disk configured, the package writes the rendered documentation to storage so you can ship it as a static artifact or publish it to an internal docs site — no PHP runtime required at read time. Wire this into a deploy or nightly job so the docs track main rather than drifting.
Export for consumers. The UI exposes a Postman collection export, which is the fastest way to hand QA and integrators a working set of requests. Point people at the export rather than maintaining a parallel collection by hand.
Use custom for the gaps. Endpoints you can't express via routes (webhooks you receive, third-party APIs you proxy, artisan-triggered jobs) can be declared manually in the custom config block with their own params and responses.
php artisan config:cache, every rules/hide_rules edit needs a config:clear (or a redeploy) before it shows up. Symptom: "I changed the config and nothing happened." This is the #1 time-waster with this package.exists:/unique: and closure-based rules don't always render as documentation. Complex Rule:: objects, Rule::when(), and closures frequently produce missing or untyped params. Don't fight it — add an explicit @LRDparam or params entry.save_to_disk is on). On a 300-route API this gets noticeable. Use hide_rules aggressively and prefer static generation for anything beyond a moderate surface area.apiResource need attention. Resource routes render with model-binding placeholders, which is usually right, but nested resources and custom key names ({order:uuid}) can produce misleading param names — override with @LRDparam.multipart/form-data. If you accept files, document the content type explicitly via annotation or custom, or consumers will assume JSON.Route::middleware() at the group level, or via a global scope, the Authorization header may not show — add it through header config.save_to_disk run published to an internal URL, plus a review step on FormRequest changes, is more reliable than asking people to remember.header, logo, and the published views let you brand the page so it reads as internal documentation rather than a dev tool. Cheap to do, meaningfully increases the chance non-backend folks actually use it."rakutentech/laravel-request-docs": "^2.44" is the right floor if you're on 13; on older Laravel you can stay earlier in the 2.x line.How can I help you explore Laravel packages today?