johnylemon / laravel-apidocs
Laravel API 文档生成工具
Requires
- php: ^7.3 || ^8.0
- laravel/framework: ^6.0 || ^7.0 || ^8.0
Requires (Dev)
- orchestra/testbench: ^6.6
- phpunit/phpunit: ^9.5
README
问题
我不喜欢编写大量的愚蠢注释,只是为了希望 API 文档能正确生成,而不出现无意义的错误。而且我并不是唯一的一个。 更多.
这个包以我喜欢的方式解决这个问题 - 通过编写 PHP 代码。
解决方案
这个包为 Laravel 路由添加了 apidocs
方法,您可以使用每天使用的代码定义路由定义。
这样您就可以
- 重用、扩展和修改现有的 API 定义
- 创建通用的端点定义,只需按需修改或创建子类
- 定义多个示例
- 定义多个样本响应
- 定义和重用参数定义
- 再次使控制器可读
入门
- 添加
johnylemon/laravel-apidocs
仓库
composer require johnylemon/laravel-apidocs
-
如果未自动注册,请注册
Johnylemon\Apidocs\Providers\ApidocsServiceProvider
提供者。 -
安装包。此命令将发布所有必需的资产。
php artisan apidocs:install
- 享受吧!
生成路由文档
这个包带有快速路由定义生成的命令。
php artisan apidocs:endpoint SampleEndpoint
全新的 SampleEndpoint
类将放置在 app\Apidocs\Endpoints
目录中。目标目录可以在您的 apidocs
配置文件中更改。
此类仅包含一个 describe
方法,您必须使用任何可用的方法来描述您的端点。例如:
<?php namespace App\Apidocs\Endpoints; use Johnylemon\Apidocs\Endpoints\Endpoint; use Johnylemon\Apidocs\Facades\Param; class SampleEndpoint extends Endpoint { public function describe(): void { $this->title('List users') ->desc('Returns paginated list of users'); } }
如您所见,我们设置了标题和描述作为端点定义。每个 方法 都返回端点实例,因此您可以将它们链接起来。
端点可用方法
- uri
- method
- group
- deprecated
- title
- description
- desc
- query
- params
- body
- header
- headers
- example
- examples
- returns
uri
设置 uri。在端点挂载时在幕后调用
$this->uri('/users');
method
设置端点方法。在端点挂载时在幕后调用
$this->method('POST');
group
将端点添加到特定的 组。组必须事先定义。
$this->group('some-group-slug');
deprecated
将端点标记为已弃用。
$this->deprecated();
title
设置端点标题
$this->title('Create user resource');
description
设置端点描述
$this->description('This endpoint contains logic for creating user resources based on provided data');
desc
description 的别名
query
定义端点查询参数。见:参数
$this->query([ 'page' => Param::type('int') ])
params
定义端点路由参数。见:参数
$this->query([ 'page' => Param::type('int') ])
body
定义端点正文参数。见:参数
$this->query([ 'page' => Param::type('int') ])
头部
定义端点头部
$this->header('x-johnylemon', 'apidocs')
头部们
一次性定义多个端点头部
$this->headers([ 'x-johnylemon' => 'apidocs', 'x-laravel' => 'framework' ])
示例
定义端点示例。可选地,您可以定义示例标题
$this->example([ 'name' => 'johnylemon', 'web' => 'https://johnylemon.dev', 'email' => 'hello@johnylemon.dev' ], 'Store user')
示例们
一次性定义多个端点示例
$this->examples([ [ 'name' => 'johny', 'web' => 'https://johnylemon.dev', 'email' => 'hello@johnylemon.dev' ], [ 'name' => 'lemon', 'web' => 'https://johnylemon.dev', 'email' => 'hello@johnylemon.dev' ] ])
返回值
定义带有状态码的示例返回值。可选地,您还可以定义响应描述。
$this->returns(201, [ 'name' => 'johny', 'web' => 'https://johnylemon.dev', 'email' => 'hello@johnylemon.dev' ], 'User created') ->returns(401, [ 'status' => 'unauthorized', ], 'Auth issue');
您还可以使用如 returns201
(或任何其他状态码) 的方法
// calling this ... $this->returns201([ 'name' => 'johny', 'web' => 'https://johnylemon.dev', 'email' => 'hello@johnylemon.dev' ], 'User created'); // ... is equivalent of this... $this->returns(201, [ 'name' => 'johny', 'web' => 'https://johnylemon.dev', 'email' => 'hello@johnylemon.dev' ], 'User created')
端点定义用法
好的,您已经创建了第一个端点定义。现在,是时候将其用作一些真实路由定义了。
让我们假设您有以下路由
Route::get('api/users', [UsersController::class, 'index']);
如果您想将 App\Apidocs\Endpoints\SampleEndpoint
类用作第一个路由的定义,您只需这样做
use App\Apidocs\Endpoints\SampleEndpoint; Route::get('api/users', [UsersController::class, 'index'])->apidocs(SampleEndpoint::class);
是的,就是这样!
现在,您唯一需要做的事情就是调用 php artisan apidocs:generate
命令,并访问 /apidocs
路由来查看其效果!
⚠️ 此包必须清除路由缓存以正确生成apidocs。 如果您在生产环境中使用路由缓存,请记住在
artisan apidocs:generate
命令之后调用artisan route:cache
因为 apidocs
方法返回端点类,您可以在路由定义期间链式调用方法。例如,您可能希望将您的路由标记为已弃用
use App\Apidocs\Endpoints\SampleEndpoint; Route::get('api/users', [UsersController::class, 'index'])->apidocs(SampleEndpoint::class)->deprecated();
因为 deprecated
方法也返回端点,因此您可以使用 其他端点方法。
⚠️ 在调用
apidocs
方法后,您不能使用特定于路由的方法,例如,比如name
方法。务必在调用所有框架特定于路由的方法之后调用apidocs
方法。
资源路由
有时您会想使用 resource
或 apiResource
方法来创建大量的典型 CRUD 端点。为了指定这些端点的定义,您必须使用它们的名称
Route::resource('posts', PostsController::class)->apidocs([ 'posts.index' => PostsIndexEndpoint::class, 'posts.store' => PostStoreEndpoint::class, ]);
如您所见,您可以省略不希望被记录的端点。
有时您可能使用 resources
或 apiResources
方法来一次性创建大量的 CRUD。由于 Laravel 不提供任何方便的钩子,使用这种方式定义的路由(以及任何其他命名路由!)可以使用 apidocs
辅助程序进行记录
// // your resoures // Route::resources([ 'users' => UsersController::class, 'posts' => PostsController::class, ]); // // defining endpoints // apidocs([ 'posts.index' => PostsIndexEndpoint::class, 'posts.store' => PostStoreEndpoint::class, 'users.index' => UsersIndexEndpoint::class, 'users.store' => UserStoreEndpoint::class, 'users.destroy' => UserStoreEndpoint::class, ]);
如前所述,您可以省略不希望被记录的端点。
参数
一些路由包含路由参数,如 {user}
段。有时您还希望使用必需或可选的查询参数。例如,POST
、PATCH
、PUT
路由几乎总是期望一些有效负载。
您可以使用 params 定义它们,并在描述端点时将它们作为数组传递给 query
、body
和 params
方法。
假设您的 index
路由(在前面展示的路由中)期望可选的 page
参数。
现在,您的定义应包含对 query
方法的额外调用,并带有可能的参数数组。之后,您的代码将看起来像这样
<?php namespace App\Apidocs\Endpoints; use Johnylemon\Apidocs\Endpoints\Endpoint; use Johnylemon\Apidocs\Facades\Param; class SampleEndpoint extends Endpoint { public function describe(): void { $this->title('List users') ->desc('Returns paginated list of users') ->query([ Param::int('page')->example(1)->default(1)->optional() ]) } }
请注意,我们没有通过数组键指定参数名称(page
)。当您在类中定义参数名称时,这不是必需的。但当然,您可以用不同的方式定义它们
use Johnylemon\Apidocs\Facades\Param; $this->query([ // parameter name will be `page` Param::int('page')->example(1)->default(1)->optional() // same effect: 'page' => Param::int('page')->example(1)->default(1)->optional() // same effect: 'page' => Param::type('int')->example(1)->default(1)->optional() // this parameter will be named `page_number` 'page_number' => Param::int('page')->example(1)->default(1)->optional() ])
如您所见,当参数名称在两个位置定义时,数组键将优先,这允许您创建可重用的 自定义参数。
您可以以相同的方式定义路由参数和请求体参数。
可用方法
类型
定义参数类型
Param::type('int');
名称
定义参数名称
Param::name('username');
description
定义参数描述
Param::description('Unique username');
desc
description 的别名。参见 描述
必填
标记参数为必填
Param::required();
可选
标记参数为可选
Param::optional();
可能值
设置参数的可能值
Param::possible([10, 100, 1000]);
枚举
possible 的别名。参见 可能值
Param::enum([10, 100, 1000]);
默认值
设置参数默认值。
Param::default(42);
示例
设置参数示例。
Param::example(42);
示例
example 的别名。参见 示例
Param 类利用了魔法 __call
方法,并允许您通过使用以下方法之一一次性定义参数类型和名称:string
、array
、boolean
、bool
、integer
或 int
use Johnylemon\Apidocs\Facades\Param; $this->query([ Param::string('slug'), // `slug` property, that should have `string` type Param::int('id'), // id `property`, that should have `int` type Param::array('roles'), // `roles` property, that should have `array` type ])
自定义参数
在处理不同的端点定义时,您可能会使用 page
或其他参数。因此,可能需要反复编写类似的内容,这可能会变得繁琐。
$this->query([ Param::int('page')->example(1)->default(1)->optional() ]);
为了解决这个问题,您可以定义 PageParam
,这样您就可以多次重用它而无需重复代码。
use App\Apidocs\Params\PageParam; (...) $this->query([ PageParam::class ]);
创建自定义参数
可以通过键入以下内容创建自定义参数:
php artisan apidocs:param PageParam
新的参数类可以在 __construct
方法中定义。
<?php namespace App\Apidocs\Params; use Johnylemon\Apidocs\Params\Param; class PageParam extends Param { public function __construct() { $this->name('page')->type('int')->default(1)->eg(42)->optional(); } }
组
Apidocs 端点将被分组。如果没有指定组,将使用默认的 non-groupped
组。
您可以使用 Johnylemon\Apidocs\Facades\Apidocs
门面定义自己的组。
use Johnylemon\Apidocs\Facades\Apidocs; Apidocs::defineGroup('users', 'Users', 'Manage users'); Apidocs::defineGroup('tickets', 'Tickets'); // Last parameter is optional
必须在注册路由之前定义组。 定义组的最理想位置是路由文件的开头。
命令
该软件包附带一些命令,这些命令将用于常见的任务。
测试
您可以使用以下命令运行测试:
vendor/bin/phpunit
许可证
MIT 许可证 (MIT)。有关详细信息,请参阅 LICENSE。
联系
下一步
- 改进示例
- 改进响应
- 改进资源
- 改进布局
由 johnylemon 用 ❤ 开发。