在 Laravel 9.0 使用 l5-swagger 套件整合 Swagger UI 文件工具

使用

安裝 darkaonline/l5-swagger 套件。

1
composer require "darkaonline/l5-swagger"

L5SwaggerServiceProvider 加至 config/app.php 檔中。

1
2
3
4
/*
* Package Service Providers...
*/
L5Swagger\L5SwaggerServiceProvider::class,

發布相關檔案。

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

如果需要認證,可以修改 config/l5-swagger.php 檔中 securitySchemes 參數,將 sanctum 取消註解,或者加上其他驗證方式。

1
2
3
4
5
6
7
8
9
10
[
'securitySchemes' => [
'sanctum' => [
'type' => 'apiKey',
'description' => 'Enter token in format (Bearer <token>)',
'name' => 'Authorization',
'in' => 'header',
],
],
],

Controller.php 中加入註解。

1
2
3
4
5
6
7
8
9
10
/**
* @OA\Info(
* version="1.0",
* title="my-api"
* )
*/
class Controller extends BaseController
{
// ...
}

ArticleController 為例,在各個方法中加入註解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
namespace App\Http\Controllers;

use App\Http\Requests\ArticleStoreRequest;
use App\Http\Requests\ArticleUpdateRequest;
use App\Http\Resources\ArticleResource;
use App\Models\Article;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Symfony\Component\HttpFoundation\Response;

class ArticleController extends Controller
{
/**
* Instantiate a new controller instance.
*/
public function __construct() {
$this->authorizeResource(Article::class);
}

/**
* Display a listing of the resource.
*
* @OA\Get(
* tags={"Article"},
* path="/api/articles",
* security={{"sanctum":{}}},
* @OA\Response(response=200, description="OK", @OA\JsonContent()),
* @OA\Response(response=401, description="Unauthorized", @OA\JsonContent()),
* )
*
* @return AnonymousResourceCollection
*/
public function index(Request $request)
{
$articles = $request->user()->articles()->with(['chain'])->get();

return ArticleResource::collection($articles);
}

/**
* Store a newly created resource in storage.
*
* @OA\Post(
* tags={"Article"},
* path="/api/articles",
* security={{"sanctum":{}}},
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(property="name", type="string", default=""),
* @OA\Property(property="address", type="string", default=""),
* @OA\Property(property="is_enabled", type="boolean", default=false),
* @OA\Property(property="chain_id", type="integer", default=0),
* ),
* ),
* ),
* @OA\Response(response=201, description="Created", @OA\JsonContent()),
* @OA\Response(response=401, description="Unauthorized", @OA\JsonContent()),
* @OA\Response(response=403, description="Forbidden", @OA\JsonContent()),
* @OA\Response(response=404, description="Not Found", @OA\JsonContent()),
* @OA\Response(response=422, description="Unprocessable Content", @OA\JsonContent()),
* )
*
* @param ArticleStoreRequest $request
* @return ArticleResource
*/
public function store(ArticleStoreRequest $request)
{
$article = $request->user()->articles()->create($request->all());

return new ArticleResource($article);
}

/**
* Display the specified resource.
*
* @OA\Get(
* tags={"Article"},
* path="/api/articles/{id}",
* security={{"sanctum":{}}},
* @OA\Parameter(
* name="id",
* description="Article ID",
* required=true,
* in="path",
* @OA\Schema(type="integer"),
* ),
* @OA\Response(response=200, description="OK", @OA\JsonContent()),
* @OA\Response(response=401, description="Unauthorized", @OA\JsonContent()),
* @OA\Response(response=403, description="Forbidden", @OA\JsonContent()),
* @OA\Response(response=404, description="Not Found", @OA\JsonContent()),
* )
*
* @param Article $article
* @return ArticleResource
*/
public function show(Article $article)
{
return new ArticleResource($article);
}

/**
* Update the specified resource in storage.
*
* @OA\Put(
* tags={"Article"},
* path="/api/articles/{id}",
* security={{"sanctum":{}}},
* @OA\Parameter(
* name="id",
* description="Article ID",
* required=true,
* in="path",
* @OA\Schema(type="integer"),
* ),
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(property="name", type="string", default=""),
* @OA\Property(property="address", type="string", default=""),
* @OA\Property(property="is_enabled", type="boolean", default=false),
* @OA\Property(property="chain_id", type="integer", default=0),
* ),
* ),
* ),
* @OA\Response(response=200, description="OK", @OA\JsonContent()),
* @OA\Response(response=401, description="Unauthorized", @OA\JsonContent()),
* @OA\Response(response=403, description="Forbidden", @OA\JsonContent()),
* @OA\Response(response=404, description="Not Found", @OA\JsonContent()),
* @OA\Response(response=422, description="Unprocessable Content", @OA\JsonContent()),
* )
*
* @param ArticleUpdateRequest $request
* @param Article $article
* @return ArticleResource
*/
public function update(ArticleUpdateRequest $request, Article $article)
{
$article->update($request->all());

return new ArticleResource($article);
}

/**
* Remove the specified resource from storage.
*
* @OA\Delete(
* tags={"Article"},
* path="/api/articles/{id}",
* security={{"sanctum":{}}},
* @OA\Parameter(
* name="id",
* description="Article ID",
* required=true,
* in="path",
* @OA\Schema(type="integer"),
* ),
* @OA\Response(response=204, description="No Content", @OA\JsonContent()),
* @OA\Response(response=401, description="Unauthorized", @OA\JsonContent()),
* @OA\Response(response=403, description="Forbidden", @OA\JsonContent()),
* @OA\Response(response=404, description="Not Found", @OA\JsonContent()),
* )
*
* @param Article $article
* @return JsonResponse
*/
public function destroy(Article $article)
{
$article->delete();

return response()->json(null, Response::HTTP_NO_CONTENT);
}
}

產生文件。

1
php artisan l5-swagger:generate

前往 http://localhost:8000/api/documentation 瀏覽。

參考資料