Recently, during the development of a new project, I found that swagger PHP has been upgraded, and it is quite different from the previous document annotation. The official documents are not very detailed. Here I will share some usage of swagger PHP v3. X with my own encapsulated cases.
Differences after upgrade Swagger-PHP v3.x Specification
introduce
API development directory
- Effect after document generation
install
- composer require darkaonline/l5-swagger
- php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"
- composer require laravel/sanctum
Swagger reusable common parameters
- I will write some public parameters of the document (such as @ OA \ OpenAPI, @ OA \ OpenAPI, @ OA \ securityscheme) into ApiController. code as follows
<?php namespace App\Apis\V1\Base\Http\Controllers; use App\Http\Controllers\Controller; abstract class ApiController extends Controller { /** * @OA\OpenApi( * @OA\Server( * url="/api/v1" * ), * @OA\Info( * title="Swagger-Demo", * version="1.0.0", * ), * ) */ /** *@OA\Tag(name="UnAuthorize", description="No user login required") */ /** *@OA\Tag(name="Authorize", description="User login required") */ /** * @OA\SecurityScheme( * scheme="Bearer", * securityScheme="Bearer", * type="apiKey", * in="header", * name="Authorization", * ) */ }
- Picture correspondence
Swagger request parameters
POST request
Before swagger PHP 3. * if we had many Post request parameters, we might write a lot of comments on the controller. Resulting in particularly redundant code. Swagger PHP 3. * I passed Form Validation To solve this problem. At the same time, the code is clearer and standardized.
- User registration list sharing , code as follows
<?php namespace App\Apis\V1\Users\Http\Controllers; use App\Apis\V1\Base\Http\Controllers\ApiController; use App\Apis\V1\Users\Http\Requests\RegisterRequest; use App\Models\User; use Illuminate\Auth\Events\Registered; use Illuminate\Support\Facades\Hash; class RegisterController extends ApiController { /** * @OA\Post ( * tags={"UnAuthorize"}, * path="/user/register", * summary="user register", * @OA\RequestBody( * @OA\MediaType( * mediaType="application/x-www-form-urlencoded", * @OA\Schema( * type="object", * ref="#/components/schemas/RegisterRequest", * ) * ) * ), * @OA\Response(response="401", description="fail", @OA\JsonContent(ref="#/components/schemas/ApiRequestException")), * @OA\Response(response="200", description="An example resource", @OA\JsonContent(type="object", @OA\Property(format="string", default="20d338931e8d6bd9466edeba78ea7dce7c7bc01aa5cc5b4735691c50a2fe3228", description="token", property="token"))), * ) */ public function register(RegisterRequest $request) { $params = $request->validated(); $user = User::query()->create([ 'name' => $params['name'], 'email' => $params['email'], 'password' => Hash::make($params['password']), ]); event(new Registered($user)); return response(["token" => $user->createToken($params['email'])->plainTextToken]); } }
In the above code, we can't see any parameters that need to be requested, @ OA\RequestBody is associated with # / components/schemas/RegisterRequest through ref, and we happen to have a form request class RegisterRequest.
In swagger PHP 3. * we can put the comments of the document post parameter into the form request class RegisterRequest. The RegisterRequest code is as follows:
<?php namespace App\Apis\V1\Users\Http\Requests; use App\Apis\V1\Base\Http\Requests\Request; /** * @OA\Schema() */ class RegisterRequest extends Request { /** * @OA\Property(format="string", default="xingxiang", description="name", property="name"), * @OA\Property(format="string", default="xingxiang@spacebib.com", description="email", property="email"), * @OA\Property(format="string", default="password", description="password", property="password"), * @OA\Property(format="string", default="password", description="password confirmation", property="password confirmation"), */ public function rules() { return [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], ]; } }
- Generate document effect
GET request
We demonstrate how to write routing parameter and request parameter annotations respectively by obtaining user list and user details.
- Routing parameter case (get user details)
/** * @OA\Get( * tags={"Authorize"}, * path="/users/{id}", * summary="get user detail", * security={{ "Bearer":{} }}, * @OA\Parameter( * name="id", * in="path", * description="user Id", * @OA\Schema( * type="integer", * format="int64" * ), * required=true, * example=1 * ), * @OA\Response(response="401", description="fail", @OA\JsonContent(ref="#/components/schemas/ApiRequestException")), * @OA\Response(response="404", description="fail", @OA\JsonContent(ref="#/components/schemas/ApiNotFoundException")), * @OA\Response(response="200", description="success",@OA\JsonContent(ref="#/components/schemas/UserResource"))) * ) * @param int $id * @return UserResource */ public function show(int $id) { try { return new UserResource(User::query()->findOrFail($id)); } catch (\Exception $exception) { throw new ApiNotFoundException(); } }
- Request parameter case (get user list)
/** * @OA\Get( * tags={"Authorize"}, * path="/users", * summary="get user list", * security={{ "Bearer":{} }}, * @OA\Parameter( * name="offset", * @OA\Schema( * type="integer", * format="int64" * ), * in="query", * description="offset", * example=0, * required=true, * ), * @OA\Parameter( * name="limit", * @OA\Schema( * type="integer", * format="int64" * ), * in="query", * description="offset", * example=10, * required=true, * ), * @OA\Response(response="401", description="fail", @OA\JsonContent(ref="#/components/schemas/ApiRequestException")), * @OA\Response(response="200", description="success",@OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/UserResource")))) * ) * @param UsersRequest $request * @param UserRepository $repository * @return AnonymousResourceCollection */ public function index( UsersRequest $request, UserRepository $repository ):AnonymousResourceCollection { $offset = $request->get('offset', 0); $limit = $request->get('limit', 10); return UserResource::collection($repository->get($offset, $limit)); }
Swagger return parameters
When Api returns, it may be a list or an object. If there are too many object parameters, we may write a lot of comment documents in the controller before, resulting in ugly code. I write the returned comments in the project development API resources To solve this problem.
Return array list
UserResource code
<?php namespace App\Apis\V1\Users\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; /** * Class UserResource * @package App\Apis\V1\Users\Http\Resources * @OA\Schema( * ) */ class UserResource extends JsonResource { /** * @OA\Property(format="int64", title="ID", default=1, description="ID", property="id"), * @OA\Property(format="string", title="name", default="xingxiang", description="name", property="name"), * @OA\Property(format="string", title="email", default="xingxiang@test.com", description="email", property="email") */ public function toArray($request) { return [ "id" => $this->id, 'name' => $this->name, 'email' => $this->email, ]; } }
effect
Return object
From the above, we can find that userresources can be reused. When @ OA\JsonContent(ref="#/components/schemas/UserResource") has type = array, it returns a list, or it is an object.
Exception return
- ApiNotFoundException code
<?php namespace App\Apis\V1\Exceptions; use Symfony\Component\HttpFoundation\Response; /** * @OA\Schema() */ class ApiNotFoundException extends ApiException { /** * The err message * @var string * * @OA\Property( * property="message", * type="string", * example="Not Found" * ) */ public function __construct(string $message = null) { parent::__construct(self::NO_FOUND_ERROR, $message ?? Response::$statusTexts[self::NO_FOUND_ERROR]); } }
summary
I passed API resources and Form Validation Disassemble the notes and meet the specification of API development directory at the same time. In the actual development of my project, I also benefited a lot based on this set of specifications.