Laravel Idea for PhpStorm - Full-featured IDE for productive artisans!

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.

Curotec logo

Curotec

Hire the top Latin American Laravel talent. Flexible engagements, budget optimized, and quality engineering.

Curotec
Bacancy logo

Bacancy

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

Bacancy
Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
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
Join the Mastering Laravel community logo

Join the Mastering Laravel community

Connect with experienced developers in a friendly, noise-free environment. Get insights, share ideas, and find support for your coding challenges. Join us today and elevate your Laravel skills!

Join the Mastering Laravel community
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
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
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
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
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Connecting Laravel Socialite with Google Client PHP Library image

Connecting Laravel Socialite with Google Client PHP Library

Read article
Create Self-Contained PHP Executables with PHPacker image

Create Self-Contained PHP Executables with PHPacker

Read article
String Manipulation with Laravel's remove Method image

String Manipulation with Laravel's remove Method

Read article
Stargazing in Your Laravel App with Intervention Zodiac image

Stargazing in Your Laravel App with Intervention Zodiac

Read article
Simple Cookie Consent Packge for Laravel image

Simple Cookie Consent Packge for Laravel

Read article
Leveraging Laravel's Conditional Ping Methods for Task Monitoring image

Leveraging Laravel's Conditional Ping Methods for Task Monitoring

Read article