Hướng dẫn tạo api document với laravel swagger

  • November 29, 2022
  • 1265

Trong bài viết trước chúng ta đã tìm hiểu cách cài đặt và sử dụng laravel swagger. Hôm nay chúng ta se đi sâu vào các khai báo hay dùng khi sử dụng laravel swagger.

1. Define api method

Định nghĩa api method với laravel l5-swagger, các method GET, POST, PUT, PATCH, DELETE đều được support đầy đủ


/**
* Get list user
*
* @OA\get(
*     path="/api/v1/users",
* )
*/

/**
* Create user
*
* @OA\Post(
*     path="/api/v1/users",
* )
*/

/**
* Update user
*
* @OA\Put(
*     path="/api/v1/users/{userId}",
* )
*/

/**
* Update user
*
* @OA\Patch(
*     path="/api/v1/users/{userId}",
* )
*/

/**
* Delete user
*
* @OA\Delete(
*     path="/api/v1/users/{userId}",
* )
*/

2. Define endpoint api

Định nghĩa endpoint api trong khai báo path


path="/api/v1/users",
// Endpoint api
// {L5_SWAGGER_CONST_HOST}/api/v1/users

3. Define Tag

Gom nhóm các api bằng cách thêm khai báo tag cho api


tags={"Users"},

4. Define auth

Với các api yêu cầu authentication cần khai báo thêm auth


// Sử dụng sanctum
security={{"sanctum": {} }},

// Không dùng sanctum
security={{ "BearerAuth":{} }},

5. Define path, request params

Đinh nghĩa path, request param


// Định nghĩa path
// {L5_SWAGGER_CONST_HOST}/api/v1/users/{userId}
 * @OA\Parameter(
 *     name="userId",
 *     in="path",
 *     description="User id",
 *     @OA\Schema(
 *         type="integer"
 *     ),
 *     required=true,
 *     example="1"
 * ),

// Đinh nghĩ request param
// Định nghĩa path
// {L5_SWAGGER_CONST_HOST}/api/v1/users?page=2
 * @OA\Parameter(
 *     name="page",
 *     in="query",
 *     description="Page",
 *     @OA\Schema(
 *         type="integer"
 *     ),
 *     example="2"
 * ),

// // {L5_SWAGGER_CONST_HOST}/api/v1/users?user_ids[]=1&user_ids[]=2
// Request param multil value
 * @OA\Parameter(
 *     name="user_ids[]",
 *     in="query",
 *     description="User ids",
 *     @OA\Schema(
 *         type="array",
 *         @OA\Items(type="integer", example="1"),
 *     ),
 * ),

// Reuse define request param
@OA\Parameter(ref="#/components/parameters/user_ids[]"),
@OA\Parameter(ref="#/components/parameters/page"), 

6. Define request body

Định nghĩa request body cho api


// Request body
     * @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(
     *              ref="#/components/schemas/CreateUserRequest"
     *         )
     * ),

// Define request body in CreateUserRequest request
<?php

namespace App\Http\Requests\Auth;

use App\Http\Requests\BaseRequest;

/**
 * @OA\Schema(
 *      properties={
 *          @OA\Property(property="name", type="string", example="huunv"),
 *          @OA\Property(property="email", type="string", example="huunv@gmail.com"),
 *          @OA\Property(property="password", type="string", example="123456"),
 *      }
 * )
 */
class CreateUserRequest extends BaseRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            'name' => 'required',
            'email' => 'required|email|unique:users,email',
            'password' => 'required'
        ];
    }
}

Request body with array


// Request body with list ids
 * @OA\Property(
 *              property="user_ids",
 *              type="array",
 *              example="[1, 2, 5]",
 *              @OA\Items(
 *                  type="integer"
 *              )
 *          ),

// Short syntax request body with array
@OA\Property(property="user_ids", example={1, 2}),

// Short syntax request body with array string value
@OA\Property(property="emails", example={"a@gmail.com", "b@gmail.com"}),

// Request body with array object
* @OA\Schema(
*      properties={
*          @OA\Property(property="question_id", type="integer", example="1"),
*          @OA\Property(property="answers", type="array",
*              @OA\Items(
*                  @OA\Property(property="id", type="integer", example="1"),
*                  @OA\Property(property="content", type="string", example="S11"),
*              ),
*          ),
*      }
* )

Request form data upload file with laravel swagger


// Request form data
* @OA\RequestBody(
*         required=true,
*         @OA\MediaType(
*             mediaType="multipart/form-data",
*             @OA\Schema(
*                  ref="#/components/schemas/UserUploadImageRequest",
*             )
*         )
*     ),

// Define request
<?php

namespace App\L5Swagger\Request\Users;

/**
 * @OA\Schema(
 *      properties={
 *          @OA\Property(property="type", type="string", example="test"),
 *          @OA\Property(property="image", type="file", format="binary"),
 *      }
 * )
 */
class UserUploadImageRequest
{
}

7. Define response success with swagger

Định nghĩa response trả về cho api


// Define response success
* @OA\Response(
*    response=200,
*    description="Successful operation",
*    @OA\JsonContent(ref="#/components/schemas/AuthResource")
* ),

// Define response in resource
<?php

namespace App\Http\Resources;

/**
 * @OA\Schema(
 *      properties={
 *          @OA\Property(
 *              property="success",
 *              type="bool",
 *              example="true"
 *          ),
 *          @OA\Property(
 *              property="data",
 *              type="object",
 *                  @OA\Property(property="token", type="string", 
 *                  example="3|PXX3pewsSBbtJhJQXXuRZ1NiLHzTvD6Bv2TBUJjm"),
 *                  @OA\Property(property="token_type", type="string", example="Bearer"),
 *          ),
 *          @OA\Property(
 *              property="message",
 *              type="string",
 *              example="success"
 *          )
 *      }
 * )
 */
class AuthResource extends SuccessResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        return [
            'token' => $this->createToken("api")->plainTextToken,
            'token_type' => 'Bearer',
        ];
    }
}

Define response sửa dụng khai báo trong model, giúp không bị lặp code. Tạo file model trong thư mục L5Swagger.


<?php

namespace App\L5Swagger\Models;

/**
 * @OA\Schema(
 *     title="User",
 *     description="User model",
 *     @OA\Xml(
 *         name="User"
 *     )
 * )
 */
class User {
    /**
     * @OA\Property(
     *     title="ID",
     *     description="ID",
     *     format="int64",
     *     example=1
     * )
     *
     * @var integer
     */
    protected $id;
    
    /**
     * @OA\Property(
     *      title="name",
     *      description="Name",
     *      example="test"
     * )
     *
     * @var string
     */
    protected $name;

    /**
     * @OA\Property(
     *      title="email",
     *      description="email",
     *      example="test@gmail.com"
     * )
     *
     * @var string
     */
    protected $email;

    /**
     * @OA\Property(
     *      title="created_at",
     *      description="Created at",
     *      example="2022-01-07 09:00:00"
     * )
     *
     * @var integer
     */
    protected $created_at;

    /**
     * @OA\Property(
     *      title="updated_at",
     *      description="Updated at",
     *      example="2022-01-07 09:00:00"
     * )
     *
     * @var integer
     */
    protected $updated_at;

    /**
     * @OA\Property(
     *      title="Company Id",
     *      description="Company of user",
     *      format="int64",
     *      example=1
     * )
     *
     * @var integer
     */
    public $company_id;


    /**
     * @OA\Property(
     *     title="Compay",
     *     description="Company of userl"
     * )
     *
     * @var \App\L5Swagger\Models\Company
     */
    private $company;
}

Define detail response, tạo response detail user


<?php

namespace App\L5Swagger\Resources\Users;

/**
 * @OA\Schema(
 *     title="UsersResource",
 *     description="Users resource",
 *     @OA\Xml(
 *         name="UserResource"
 *     ),
 * )
 */
class UserResource {
    /**
     * @OA\Property(
     *     title="Data",
     *     description="Data wrapper"
     * )
     *
     * @var \App\L5Swagger\Models\User
     */
    protected $data;

    /**
     * @OA\Property(
     *     title="Message success",
     *     description="Message success",
     *     example="Success",
     * )
     *
     * @var string
     */
    protected $message;

    /**
     * @OA\Property(
     *     title="Response success",
     *     description="Response success",
     *     example="true",
     * )
     *
     * @var bool
     */
    protected $success;
}

Define response collection, tạo response trả về là collection


<?php

namespace App\L5Swagger\Resources\Users;

/**
 * @OA\Schema(
 *     title="UsersResource",
 *     description="Users resource",
 *     @OA\Xml(
 *         name="UsersResource"
 *     ),
 * )
 */
class UsersResource {
    /**
     * @OA\Property(
     *     title="Data",
     *     description="Data wrapper"
     * )
     *
     * @var \App\L5Swagger\Models\User[]
     */
    protected $data;

    /**
     * @OA\Property(
     *     title="Message success",
     *     description="Message success",
     *     example="Success",
     * )
     *
     * @var string
     */
    protected $message;

    /**
     * @OA\Property(
     *     title="Response success",
     *     description="Response success",
     *     example="true",
     * )
     *
     * @var bool
     */
    protected $success;
}

8. Define response error with swagger

Định nghĩa response error trả về 400


 *     @OA\Response(
     *         response=400,
     *         description="Successful",
     *         @OA\JsonContent(
     *              properties={
     *                  @OA\Property(property="success", type="boolean", example="false"),
     *                  @OA\Property(property="data", type="object"),
     *                  @OA\Property(property="message", type="string", example="Failure!")
     *              }
     *         )
     *     )
     * )

Định nghĩa nhiều error cùng 1 mã lỗi 400


 *     @OA\Response(
     *          response="400",
     *          description="Errors",
     *          @OA\JsonContent(
     *              examples={
     *                  @OA\Schema(example="error_1", * 
     *                  ref="#/components/examples/CreateUser400Response_1"),
     *                  @OA\Schema(example="error_2", 
     *                  ref="#/components/examples/CreateUser400Response_2"),
     *              }
     *          )
     *     )
     * )

// Define multi message
<?php

namespace App\L5Swagger\Resources\Users;

/**
 * @OA\Examples(
 *      summary="Error 1",
 *      example="CreateUser400Response_1",
 *      value={
 *          "success": false,
 *          "data": {},
 *          "message": "Error 1",
 *      }
 * )
 * @OA\Examples(
 *      summary="Error 2",
 *      example="CreateUser400Response_2",
 *      value={
 *          "success": false,
 *          "data": {},
 *          "message": "Error 2",
 *      }
 * )
 */
class CreateUser400Response
{
}

Định nghĩa error 500


*     @OA\Response(
     *         response=500,
     *         description="Error",
     *         @OA\JsonContent(ref="#/components/schemas/CreateUser500Response")
     *     )
     * )

// Define error 500
<?php

namespace App\L5Swagger\Resources\Users;

/**
 * @OA\Schema(
 *      properties={
 *          @OA\Property(property="success", type="boolean", example="false"),
 *          @OA\Property(property="data", type="object"),
 *          @OA\Property(property="message", type="string", example="Server error")
 *      }
 * )
 */
class CreateUser500Response
{
}

Tổng kết

Như vậy là chúng ta đã có thể tự tin định nghĩa các api document khi sử dụng swagger. Các bạn hay sử dụng swagger như thế nào? Hãy comment bên dưới. Thanks for reading...