Here, I will describe usage of Swagger, list the L5 Swagger basic configurations, provide templates to document POST and GET API (Application Programming Interface).
What does L5 Swagger provide?
For PHP developers, here in particular those using Laravel framework, L5 Swagger provide the means to document your API and have it presented in the form of a web page for quick browsing of available APIs and testing its results.
Currently here are good to know facts
- Its is developed as a wrapper on swagger-php and swagger-api specifically for Laravel framework.
- It supports OpenAPI (formerly known as Swagger), a specification for documentation of RESTful API irrespective of technology, like PHP, Java or .Net.
- L5-Swagger currently supports OpenAPI version 3.0 and 3.1. Its project page is https://github.com/DarkaOnLine/L5-Swagger
- It supports at least PHP version 7.2. PHP 8.1 introduces the use of attributes.
- An online swagger editor is available at swagger.io
My example hinges on PHP 7.4 with darkaonline/l5-swagger version 8.5.1. Will just dump example of code and configurations here. Details will be explained at another time. Good luck.
Quick notes to setup of Swagger in a ready Laravel version 7 or 10 project;
composer require "darkaonline/l5-swagger"
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"
php artisan l5-swagger:generate
Customisation can be done by editing config/swagger.php, which can be continued in future articles.
Security
Security options are;
- None - no security is set to access API
- Basic Auth - Username and password is set for each request
- API Key - A key is set for each request
- OATH - An authorisation scheme for each request
Example 1 - API to login
Request
Headers:
App-Key: SOmeVeryLongKey
Body form-data:
username: example@some.email.example
password: password
API returns with HTTP code 200
{
"user_id": 4142,
"token": "173892|HxOQJBfDgDgDgaqgCpSS1rh7UY7HWdurtanHhq7"
}
API returns with HTTP code 400
{
"message": "These credentials do not match our records."
}
Example 2 - API to retrieve user profile
Request
Headers:
API returns with HTTP code 200
{
"status": 0,
"message": null,
"data": [
{
"id": 385,
"name": "Bintulu",
"address1": "no.3 River side, Sarawak",
"address2": null,
"introduction": "Software architect and Postgresql architect",
"phone": "1234512345",
"email": "bintulu@some.email.example",
"notes": "Call by phone"
}
],
"timestamp": "2023-03-17T10:00:09"
}
Swagger documentation
Swagger group for Login
Swagger for login
Added example to submit with multi/form-data (which is not necessary for login)
Swagger for user profile
The Code
Our example api.php and UserController.php
routes/api.php
Route::post('/login', 'API\UserController@login');
Route::get('/user/profile', 'API\UserController@login');
Function login in app/Http/Controllers/API/UserController.php
/**
* @OA\Post(
* path="/api/login",
* tags={"Login"},
* security={{"appkey":{}}},
* @OA\RequestBody( required=true, description="Login",
* @OA\MediaType(
* mediaType="multipart/form-data",
* @OA\Schema(
* required={"username","password"},
* @OA\Property(
* property="username",
* type="string",
* description="user login id of type email"
* ),
* @OA\Property(
* property="password",
* type="password"
*
* ),
* ),
* ),
*
* ),
* @OA\Response(response="200", description="An example endpoint",
* @OA\JsonContent(
* @OA\Property(property="id", type="number", example="1957"),
* @OA\Property(property="token", type="string", example="173892|HxOQJBfDgDgDgaqgCpSS1rh7UY7HWdurtanHhq7"),
* ),
* ),
* @OA\Response(response="400", description="The id or password incorrect.",
* @OA\JsonContent(
* @OA\Property(property="message", type="string", example="These credentials do not match our records."),
* ),
* ),
* )
*/
Function getUserProfile in app/Http/Controllers/API/UserController.php
/**
* @OA\Get(
* path="/api/user/profile",
* tags={"Login"},
* summary="Retrieve user profile",
* description="Retrieve user profile based on user auth detected. No parameters are required",
* operationId="getUserProfile",
* security={{"bearer_token":{}}},
* @OA\Parameter(
* name="App-Key",
* in="header",
* description="App-Key",
* example=L5_SWAGGER_APPKEY
* ),
*
* @OA\Response(response=401, description="User not authenticated",
* @OA\JsonContent(
* @OA\Property(property="status", type="number", example="1"),
* @OA\Property(property="message", type="string", example="Not authenticated"),
* @OA\Property(property="data", type="string", example=null),
* @OA\Property(property="timestamp", type="string", example="2023-03-17T10:00:09"),
* ),
* ),
* @OA\Response(
* response=200,
* description="Success",
* @OA\JsonContent(
* @OA\Property(property="status", type="number"),
* @OA\Property(property="message", type="string", example=null),
* @OA\Property(property="data", type="array",
* @OA\Items(
* @OA\Property(property="id", type="number", example=385),
* @OA\Property(property="name", type="string", example="Bintulu"),
* @OA\Property(property="address1", type="string", example="no.3 River side, Sarawak"),
* @OA\Property(property="address2", type="string", example=null),
* @OA\Property(property="introduction", type="string", example="Software architect and Postgresql architect"),
* @OA\Property(property="phone", type="string", example="1234512345"),
* @OA\Property(property="email", type="string", example="bintulu@some.email.example"),
* @OA\Property(property="notes", type="string", example="Call by phone"),
* ),
* ),
* @OA\Property(property="timestamp", type="string", example="2023-03-17T10:00:09"),
* ),
* ),
* ),
*/