How to Document Your Laravel API Using Swagger

How to Document Your Laravel API Using Swagger

How to Document Your Laravel API Using Swagger

Introduction

API documentation is essential for developers to understand and efficiently use your API. Swagger (OpenAPI) is a popular tool that helps generate interactive and user-friendly API documentation. In this guide, we’ll walk through the process of integrating Swagger into a Laravel application to document API endpoints.

Prerequisites

Before getting started, make sure you have:

  • A Laravel project set up
  • Composer installed
  • Basic knowledge of Laravel API development

Step 1: Install Swagger in Laravel

To use Swagger in Laravel, install the darkaonline/l5-swagger package via Composer:

composer require darkaonline/l5-swagger

Next, publish the configuration file by running:

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

This command generates the config/l5-swagger.php configuration file.

Step 2: Define Global API Information

To define the global API information, update your base Controller (app/Http/Controllers/Controller.php):

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

/**
 * @OA\OpenApi(
 *     @OA\Info(
 *         version="1.0",
 *         title="Laravel Swagger API",
 *         description="Laravel Swagger API Documentation",
 *     )
 * )
*/
class Controller extends BaseController
{
    use AuthorizesRequests, ValidatesRequests;
}

Step 3: Add Swagger Annotations to Your API Controllers

Swagger uses annotations (comments) in your controller methods to generate documentation. 

Below is an example of how to document an API endpoint:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\Request;

/**
 * @OA\Tag(
 *     name="Products",
 *     description="Operations related to products"
 * )
 */

/**
 * @OA\Schema(
 *     schema="Product",
 *     type="object",
 *     required={"name", "sku", "price", "stock_quantity"},
 *     @OA\Property(property="name", type="string"),
 *     @OA\Property(property="sku", type="string"),
 *     @OA\Property(property="price", type="number", format="float"),
 *     @OA\Property(property="stock_quantity", type="integer"),
 * )
 */
class ProductController extends Controller
{


    /**
     * @OA\Get(
     *     path="/api/products",
     *     summary="Fetch a paginated list of products with filters by name",
     *     tags={"Products"},
     *     @OA\Parameter(
     *         name="name",
     *         in="query",
     *         description="Filter by product name",
     *         required=false,
     *         @OA\Schema(type="string")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="A paginated list of products",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="data", type="array",
     *                 @OA\Items(ref="#/components/schemas/Product")
     *             ),
     *             @OA\Property(property="current_page", type="integer"),
     *             @OA\Property(property="last_page", type="integer"),
     *             @OA\Property(property="per_page", type="integer"),
     *             @OA\Property(property="total", type="integer")
     *         )
     *     )
     * )
     */
    public function index(Request $request)
    {
        if($request->name){
            $products = Product::where("name", "like","%$request->name%")->paginate(10);
        }else{
            $products = Product::paginate(10);
        }
        return response()->json($products);
    }

    /**
     * @OA\Post(
     *     path="/api/products",
     *     summary="Create a new product",
     *     tags={"Products"},
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(ref="#/components/schemas/Product")
     *     ),
     *     @OA\Response(
     *         response=201,
     *         description="Product created successfully",
     *         @OA\JsonContent(ref="#/components/schemas/Product")
     *     )
     * )
     */
    public function store(Request $request)
    {
        $product = Product::create($request->all());
        return response()->json($product, 201);
    }

    /**
     * @OA\Get(
     *     path="/api/products/{id}",
     *     summary="Get details of a specific product",
     *     tags={"Products"},
     *     @OA\Parameter(
     *         name="id",
     *         in="path",
     *         description="ID of the product",
     *         required=true,
     *         @OA\Schema(type="integer")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Product details",
     *         @OA\JsonContent(ref="#/components/schemas/Product")
     *     )
     * )
     */
    public function show($id)
    {
        $product = Product::find($id);
        return response()->json($product);
    }

    /**
     * @OA\Put(
     *     path="/api/products/{id}",
     *     summary="Update an existing product",
     *     tags={"Products"},
     *     @OA\Parameter(
     *         name="id",
     *         in="path",
     *         description="ID of the product",
     *         required=true,
     *         @OA\Schema(type="integer")
     *     ),
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(ref="#/components/schemas/Product")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Product updated successfully",
     *         @OA\JsonContent(ref="#/components/schemas/Product")
     *     )
     * )
     */
    public function update(Request $request, $id)
    {
        $product = Product::find($id)->update($request->all());
        return response()->json($product);
    }

    /**
     * @OA\Delete(
     *     path="/api/products/{id}",
     *     summary="Delete a product",
     *     tags={"Products"},
     *     @OA\Parameter(
     *         name="id",
     *         in="path",
     *         description="ID of the product",
     *         required=true,
     *         @OA\Schema(type="integer")
     *     ),
     *     @OA\Response(
     *         response=204,
     *         description="Product deleted successfully"
     *     )
     * )
     */
    public function destroy($id)
    {
        Product::find($id)->delete();
        return response()->json(null, 204);
    }
}
 

Step 5: Generate Swagger Documentation

Run the following command to generate the API documentation:

php artisan l5-swagger:generate

Now, open your browser and visit:

http://your-app-url/api/documentation

This will display an interactive Swagger UI with all documented API endpoints.

Step 6: Automate Documentation Updates

Instead of manually generating the documentation, you can set L5_SWAGGER_GENERATE_ALWAYS=true in the .env file to automatically update the documentation whenever the application runs.

Conclusion

Swagger simplifies API documentation, making it easier for developers to interact with your API. By following the steps outlined in this guide, you can effectively document your Laravel API and improve maintainability.

 

Join Our Newsletter Now

Get E-mail updates about us.