最近在新專案開發的過程中我發現 swagger-php
升級了版本,而且和以前的文件註釋寫法有了蠻多的差別。官方文件也寫的不是很詳細,在這裡我將結合自己封裝的案例將 Swagger-PHP v3.x
的一些用法分享給大家。
介紹
API 開發目錄
- 文件生成後效果
安裝
composer require darkaonline/l5-swagger
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"
composer require laravel/sanctum
Swagger 可複用的公用引數
- 我會把文件的一些公共引數( 如
@OA\OpenApi
,@OA\OpenApi
,@OA\SecurityScheme
)寫到ApiController
裡面。程式碼如下
<?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",
* )
*/
}
- 圖片對應
Swagger 請求引數
POST 請求
在 swagger-php 3.*
以前我們如果 Post 請求引數很多,那麼在控制器我們可能寫很多的註釋。導致程式碼特別冗餘。 swagger-php 3.*
我是通過 表單驗證 來解決這個問題的。同時程式碼也更清晰規範。
- 使用者註冊案列分享,程式碼如下
<?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]);
}
}
在上面程式碼中,我們看不到任何需要請求的引數,@OA\RequestBody
通過 ref
關聯到 #/components/schemas/RegisterRequest
,而我們剛好有個表單請求類 RegisterRequest
。在 swagger-php 3.*
我們可以把文件 post 引數的註釋放到表單請求類 RegisterRequest
。RegisterRequest
程式碼如下:
<?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'],
];
}
}
- 生成文件效果
GET 請求
我們以獲取使用者列表和獲取使用者詳情,分別演示路由引數和請求引數註釋如何編寫。
- 路由引數案例(獲取使用者詳情)
/**
* @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();
}
}
- 請求引數案例(獲取使用者列表)
/**
* @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 返回引數
在 Api 返回的時候,有可能是列表,有可能是物件。如果物件引數特別多,按以前我們可能在控制器寫很多註釋文件,導致程式碼很難看,我在專案開發中是將返回的註釋寫到 API 資源 來解決這個問題。
返回陣列列表
UserResource 程式碼
<?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,
];
}
}
效果
返回物件
從上面我們可以發現 UserResource
是可以複用的,當 @OA\JsonContent(ref="#/components/schemas/UserResource")
裡面有 type = array
返回的就是列表,不然就是物件。
異常返回
- ApiNotFoundException 程式碼
<?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]);
}
}
總結
我是通過 API 資源 和 表單驗證 去拆解註釋,同時達到 API 開發目錄的規範。在我專案實際開發中,自己也基於這套規範收益良多。
本作品採用《CC 協議》,轉載必須註明作者和本文連結