API Documentation in Laravel

Andrea Pollastri
3 min readMay 19, 2023

In this article, I would like to explain how to generate a Swagger file into a Laravel project. Swagger allows you to describe the structure of your APIs via Open API Specification and supplies one interactive UI API documentation.

The first step is the installation of L5 Swagger Extention via Composer:

composer require "darkaonline/l5-swagger"

and the publishing of its vendor:

php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

Now we have to configure the Extention editing config/l5-swagger.php file:


'api' => [
'title' => 'Foo Bar Project',
],

'routes' => [
'api' => 'api/docs',
],

'paths' => [
'docs' => public_path('api-docs'),
],

'docs_json' => 'swagger.json',
'docs_yaml' => 'swagger.yaml',

If you are using “Sanctum” to secure your APIs, uncomment the Auth/Sanctum section.

Then add this notation to the app/Control/Http/Controller.php file:

/**
* @OA\Info(
* version="1.0",
* title="Foo Bar Project",
* description="API Documentation for Foo Bar Project"
* )
*/

If you are using Sanctum, add this notation snippet:

/**
* @OA\SecurityScheme(
* securityScheme="sanctum",
* type="http",
* scheme="sanctum"
* )
*/

Use notations to describe every API endpoint via Controllers methods:

/**
* @OA\Get(
* path="/api/users",
* summary="Users List",
* tags={"Users"},
* description="Users List Endpoint.",
* @OA\Parameter(in="header", required=false, name="application_id", @OA\Schema(type="integer")),
* @OA\Parameter(in="path", required=false, name="group", @OA\Schema(type="string")),
* @OA\Parameter(in="query", required=false, name="search", @OA\Schema(type="string")),
* @OA\Response(response=200, description="Successful request"),
* @OA\Response(response=422, description="Invalid payload"),
* @OA\Response(response=401, description="Unauthorized")
* )
*/
public function index(Request $request)
{

If you are using Sanctum, add this line:

security={ {"sanctum": {} }},

To describe APIs use Open API and L5 Extention documentation:

The following snippets are examples:

/**   
* @OA\Post(
* path="/api/users",
* summary="Users Store",
* tags={"Users"},
* description="Create User Endpoint",
* @OA\RequestBody(
* required=true,
* @OA\MediaType(
* mediaType="multipart/form-data",
* @OA\Schema(
* @OA\Property(property="name", type="string"),
* @OA\Property(property="email", type="string"),
* @OA\Property(property="password", type="string"),
* required={"email", "password"}
* )
* )
* ),
* @OA\Response(response=201, description="Successful Created"),
* @OA\Response(response=422, description="Invalid payload")
* )
*/
public function store(Request $request)
{
/**
* @OA\Put(
* path="/api/users",
* summary="Users Update",
* tags={"Manager", "User"},
* @OA\RequestBody(
* @OA\JsonContent(
* type="object",
* @OA\Property(property="email", type="string"),
* @OA\Property(property="password", type="string"),
* )
* ),
* @OA\Response(response=200, description="Successful request"),
* @OA\Response(response=422, description="Invalid payload"),
* @OA\Response(response=401, description="Unauthorized")
* )
*/
public function update(Request $request)
/**
* @OA\Schema(
* schema="UserRegistration",
* title="User Schema",
* @OA\Property(property="id", description="User ID", type="integer"),
* @OA\Property(property="team_id", description="Team ID", type="integer")
* @OA\Parameter(in="query", required=false, name="from", @OA\Schema(type="string", format="date", pattern="\d{4}-\d{2}-\d{2}", example="2023-01-01"), description="Start Date"),
* @OA\Parameter(in="query", required=false, name="to", @OA\Schema(type="string", format="date", pattern="\d{4}-\d{2}-\d{2}", example="2023-12-31"), description="End Date"),
* )
* @OA\Post(
* path="/api/register",
* summary="Registration",
* tags={"Auth"},
* description="Registration Endpoint.",
* @OA\RequestBody(
* required=true,
* @OA\MediaType(
* mediaType="multipart/form-data",
* @OA\Schema(
* @OA\Property(
* property="email",
* type="string",
* description="User email",
* ),
* @OA\Property(
* property="photo",
* type="file",
* description="User photo",
* ),
* required={"email"}
* )
* )
* ),
* @OA\Response(
* response=200,
* description="Successful user registration",
* @OA\JsonContent(
* @OA\Property(
* property="data",
* type="object",
* ref="#/components/schemas/UserRegistration"
* )
* ),
* )
*/
public function register(AuthRegistrationRequest $request)
{

To generate a Swagger file, run this command:

php artisan l5-swagger:generate

Now you can visit /api/docs URL and discover a basic Swagger UI.

You can customize your project Swagger UI, using this code:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{config('l5-swagger.documentations.'.$documentation.'.api.title')}}</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.18.3/swagger-ui.css' />
<style>html { box-sizing: border-box; overflow: -moz-scrollbars-vertical; overflow-y: scroll; } *,*:before,*:after { box-sizing: inherit; } body { margin:0; background: #fafafa; }</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.18.3/swagger-ui-standalone-preset.min.js' ></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.18.3/swagger-ui-bundle.js' ></script>
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
requestInterceptor: function(request) {
request.headers['accept'] = 'application/json';
return request;
},
url: window.location.protocol + "//" + window.location.host + "/api-docs/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
layout: "StandaloneLayout"
})
window.ui = ui
}
</script>
</body>
</html>

Now it’s your turn… enjoy your next Project’s Swagger!

--

--