Outsource Laravel Development Partner - $3200/Month | Bacancy

In-depth guide on documenting API requests with Scramble

Last updated on by

In-depth guide on documenting API requests with Scramble image

When documenting the endpoints of your API, you can mentally split the task into documenting the request part (authentication, request body, request parameters) and documenting the response part. In this guide, we'll do a deep dive into request documentation.

Automatically generated request parameters and body

The main goal of Scramble is to generate as much API documentation as possible without requiring you to write any annotations manually. Writing a PHPDoc with all parameters and the request body is a tedious task and an error-prone approach. If some detail about the request changes, you need to update the PHPDoc. Sooner or later, a correction will be missed, and the API documentation will become outdated.

If you think about it, there is already a ton of information about API requests within the codebase! Validation rules, route path parameters, and method calls on $request — all of this data describes the requests of API endpoints.

Scramble uses this information to automatically generate a basic request documentation that describes the data types that can be sent to the API.

When model binding is used, Scramble documents path parameters according to the model key type. As expected, integer keys are documented as integers, and uuid keys are documented as strings with the uuid format:

Add descriptions and examples to parameters

On top of Scramble-generated request structure and parameters, you can add descriptions, examples, and defaults. You can also add other parameters in case Scramble misses something or change a parameter type.

The easiest way to do that is to use attributes:

#[BodyParameter('name', 'The name of the company')]
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string'],
]);
...
}

You can also add descriptions to parameters using PHPDoc comments on the rules.

public function store(Request $request)
{
$request->validate([
// The name of the company.
'name' => ['required', 'string'],
]);
...
}

Add parameters to a single endpoint manually

Using the source code for request API documentation, Scramble will cover most cases. However, it doesn't automatically document request headers or cookies.

You can do that using attributes. For example, let's say you retrieve a header value in your controller like so:

$request->header('X-Header-Name');

This can be documented using the #[HeaderParameter] attribute:

#[HeaderParameter('X-Header-Name', 'The name of the header.', type: 'string')]

If you'd like to document cookies, you can use the #[CookieParameter] attribute.

$value = $request->cookie('name');

Document it like so:

#[CookieParameter('name', 'The cookie.', type: 'string')]

Using #[PathParameter], #[QueryParameter], and #[BodyParameter], you can also document the corresponding parameters of a request.

To document query parameters sent to the API in a query string, like /api/books?page=1, use the #[QueryParameter] attribute:

#[QueryParameter('page', 'The page number.', type: 'int')]

Using #[PathParameter], you can document path parameters that are part of the route. For example, there is a book path parameter in the route GET /api/book/{book}.

#[PathParameter('book', 'The book to show')]

If you need to add a request body parameter, use the #[BodyParameter] attribute.

#[BodyParameter('project_id', type: 'int')

You can even use dots like you would in validation rules to create deep structures:

#[BodyParameter('projects.*.id', 'The ID of the project', type: 'int')]
#[BodyParameter('projects.*.name', 'The name of the project', type: 'string')]

By default, attributes "attach" information to parameters inferred automatically from the codebase. To ignore automatically inferred parameter information, pass infer: false to the attribute. This will keep only manually provided parameter information:

#[QueryParameter('page', 'The page number.', type: 'int', infer: false)]

Add parameters documentation to multiple endpoints

Often, headers and cookies are retrieved in middleware, making them applicable to all endpoints. Scramble gives you full control over the resulting OpenAPI document using transformers.

Operation transformers allow you to add additional documentation information to all endpoints. You can also inspect the middleware and apply the documentation if a specific middleware exists on a route.

Consider this example. We have a global middleware that logs the request ID taken from the headers. This middleware runs whenever any API route is hit, so we want to document it for all routes.

<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class LogRequestId
{
public function handle(Request $request, Closure $next): Response
{
if ($id = $request->header('X-Request-ID')) {
info("Request ID: $id (url: {$request->url()}");
}
 
return $next($request);
}
}

Now, we can add this header to all routes using an operation transformer in the boot method of a service provider:

public function boot(): void
{
Scramble::configure()
->withOperationTransformers(function (Operation $operation) {
$operation->parameters[] = (new Parameter('X-Request-ID', 'header'))
->description('The ID of the request for better request visibility.')
->setSchema(Schema::fromType(new StringType));
});
}

And now, the X-Request-ID header is added to all API routes.

Add endpoint's title and description

To provide more context for an endpoint, you can add a title and description to its documentation. This can be done simply by adding a PHPDoc comment. The first line is treated as the endpoint title, while the lines after that are treated as the description. You can use CommonMark Markdown formatting for the description.

Document authentication

If your API requires authentication, you can document it using a document transformer and specifying the default authentication mechanism of your API.

Document transformers are defined in the boot method of a service provider:

public function boot()
{
Scramble::configure()
->withDocumentTransformers(function (OpenApi $openApi) {
$openApi->secure(
SecurityScheme::http('bearer')
);
});
}

If an endpoint is public (for example, user registration), you can mark that endpoint as not requiring authentication:

/**
* @unauthenticated
*/
public function store(Request $request)
{
...
}

By using operation transformers, you can even inspect the middleware on a route and automatically remove the authentication requirement for endpoints that do not have the auth middleware:

public function boot()
{
Scramble::configure()
->withOperationTransformers(function (Operation $operation, RouteInfo $routeInfo) {
$routeMiddleware = $routeInfo->route->gatherMiddleware();
 
$hasAuthMiddleware = collect($routeMiddleware)->contains(
fn ($m) => Str::startsWith($m, 'auth:')
);
 
if (! $hasAuthMiddleware) {
$operation->security = [];
}
})
}

Group endpoints and sort groups

To group endpoints, you can use the #[Group] attribute on a controller (which will group all endpoints of that controller) and on a controller's method.

#[Group('Companies API')]
class CompaniesController {...}

You can sort the groups by providing a weight argument to the #[Group] attribute:

#[Group('Domains API', weight: 2)]
class DomainsController {...}

Conclusion

Using Scramble, you can generate up-to-date API documentation based on your source code. This saves time and ensures that your API documentation remains accurate. Additionally, you can enhance the documentation by adding parameter descriptions, titles, examples, and default values, allowing you to document all the details of your API.

Give Scramble a try if you haven't already: https://scramble.dedoc.co

Also, check out the demo documentation generated by Scramble: https://scramble.dedoc.co/demo/scramble. You will find “Go to GitHub” links in the documentation, allowing you to quickly jump to the source code from which each documentation piece was generated.

Roman Lytvynenko photo

Working on https://scramble.dedoc.co – Modern Laravel OpenAPI (Swagger) documentation generator.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Curotec

Curotec helps software teams hire the best Laravel developers in Latin America. Click for rates and to learn more about how it works.

Visit Curotec
Curotec logo

Curotec

World class Laravel experts with GenAI dev skills. LATAM-based, embedded engineers that ship fast, communicate clearly, and elevate your product. No bloat, no BS.

Curotec
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $3200/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Cut PHP Code Review Time & Bugs into Half with CodeRabbit logo

Cut PHP Code Review Time & Bugs into Half with CodeRabbit

CodeRabbit is an AI-powered code review tool that specializes in PHP and Laravel, running PHPStan and offering automated PR analysis, security checks, and custom review features while remaining free for open-source projects.

Cut PHP Code Review Time & Bugs into Half with CodeRabbit
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit

The latest

View all →
Laravel 12.44 Adds HTTP Client afterResponse() Callbacks image

Laravel 12.44 Adds HTTP Client afterResponse() Callbacks

Read article
Handle Nested Data Structures in PHP with the Data Block Package image

Handle Nested Data Structures in PHP with the Data Block Package

Read article
Detect and Clean Up Unchanged Vendor Files with Laravel Vendor Cleanup image

Detect and Clean Up Unchanged Vendor Files with Laravel Vendor Cleanup

Read article
Seamless PropelAuth Integration in Laravel with Earhart image

Seamless PropelAuth Integration in Laravel with Earhart

Read article
Laravel API Route image

Laravel API Route

Read article
Laravel News 2025 Recap image

Laravel News 2025 Recap

Read article