asseco-voice / laravel-open-api
Laravel OpenAPI 生成器
Requires
- php: ^8.1
- laravel/framework: ^10.0
- mpociot/reflection-docblock: ^1.0
- symfony/yaml: ^6.0
Requires (Dev)
- fakerphp/faker: ^1.9.1
- mockery/mockery: ^1.4.4
- orchestra/testbench: ^8.5
- phpunit/phpunit: ^10.0
README
Laravel OpenApi 生成器
此包提供从现有路由轻松生成 OpenApi YML 的功能。
目标是尽可能减少生成 API 文档所需的工作,因此包将尝试假设许多事情,例如从控制器名称推断模型、基于实际表的实际请求和响应参数等。
对于自定义输入/输出,将提供选项。
安装
通过 composer 安装此包。它将自动注册为 Laravel 服务提供者。
composer require asseco-voice/laravel-open-api
使用方法
运行 php artisan asseco:open-api
命令将在 project_root/open-api.yml
处生成一个新的 .yml
文件。
默认提供的功能
- 读取所有路由
- 从控制器名称推断模型名称
- 自动分组(标记)
- 获取标题和描述
- 生成请求和响应参数
对于此约定未涵盖的情况,请参阅 覆盖默认值部分。
对于其他调整,请参阅 配置。
由于需要为每个找到的模型请求数据库模式,因此首次运行可能需要几秒钟。这将进行缓存,因此后续运行将更快。
简单的默认示例
给定控制器
class UserController extends Controller
{
/**
* Store a newly created resource in storage.
*
* Create new User object and store it in DB.
*/
public function store(Request $request): JsonResponse
{
$user = User::query()->create($request->all());
return response()->json($user);
}
...
- 命令将推断
User
作为控制器的主体模型 - 标题:
在存储中存储新创建的资源。
- 描述:
创建新的 User 对象并将其存储在数据库中。
- 请求数据:
User
模型表属性,没有id
、created_at
、updated_at
属性 - 响应数据: 完整的
User
模型表属性
覆盖默认值
通过文档块中的控制器和方法注释处理自定义情况
/**
* My controller doc block
*
* @annotation random annotation
*/
class MyController extends Controller
{
/**
* My method doc block
*
* @annotation another random annotation
*/
public function index()
{
...
}
...
}
分组(标记)
当谈到“分组”时,我们实际上是在谈论 OpenApi 的“标记”。
默认情况下,命令将采用控制器名称,从其中删除 Controller
并用空格分割 PascalCase
(例如,SysUserController
结果为 Sys User
分组名称)。
- 控制器文档块中的
@group
将覆盖默认分组。 - 方法文档块中的
@group
将覆盖默认分组和控制器分组,使其具有最高优先级。
可以堆叠多个分组注释。
模型
模型用于尝试自动为标准 Laravel CRUD 函数生成输入和输出。
输入(请求): 模型数据库模式,具有仅填充属性或除受保护的之外的所有属性。填充属性具有优先级,如果存在填充属性,则忽略受保护的属性。
输出(响应): 完整的模型数据库模式,没有隐藏字段。
没有任何模型关联是完全有效的。在这种情况下,将不会执行需要现有模型类的任何自动操作。
默认情况下,模型名称从控制器名称中提取。要更改此行为,您有几个选项
- 将特定控制器映射到特定模型。有关详细信息,请参阅 配置。
- 在控制器中包含
@model
标记- 指定命名空间模型将使用该模型
@model My\Namespaced\Model
- 未指定命名空间时,将使用控制器的命名空间
@model Model
- 指定命名空间模型将使用该模型
控制器标签的优先级高于配置映射。如果两者都存在,且控制器标签失败,配置将尝试获取模型。两个都失败将导致模型为 null
。
可以排除模型的一部分用于请求
@exclude attribute1 attribute2
是一个空格分隔的指定模型属性列表,这些属性将不会包含在请求数据中。
路径参数
默认情况下,路径参数将被设置为整数(假设大多数路径参数是模型ID)。如果您想使用UUID,可以在 asseco-open-api
配置文件中将 service_uses_uuid
设置为 true 来更改此设置。
通过在方法文档块中包含以下内容来覆盖它们
@path
将覆盖默认获取的内容。您必须按照以下约定提供它:@path name type description
,其中name
- 参数名称。type
- OpenApi数据类型。description
- 将作为参数描述设置的文本(不是必需的,默认为空,因此可以省略)。
示例
@path name type
@path name type Some description
无法设置路径参数 required
属性。因为它自动设置为 true,因为OpenApi不支持可选路径参数(尽管Laravel支持)。
操作ID
默认情况下,operationId
将根据控制器/HTTP方法映射和模型名称为每个路由生成。如果您想覆盖默认值,可以使用 @operationId
提供不同的后缀给操作ID(将替换自动生成的模型)。
由于在更新路由映射到PUT和PATCH动词时可能存在冲突,因此附加的控制器/HTTP方法将保持不变。
示例
// Provided for an show() method:
@operationId suffix
// this will output getSuffix
// Provided for an update() method:
@operationId suffix
// this will output putSuffix and patchSuffix
请求/响应参数
默认情况下,请求/响应参数将从模型 提取。
通过在方法文档块中包含 @request
或/和 @response
来覆盖它们。
对于 @request
的示例,对于 @response
工作方式相同
@request
将覆盖默认获取的内容。您必须按照以下约定提供它:@request name type required description
,其中name
- 参数名称。type
- OpenApi数据类型。required
- 表示参数是否必需的布尔值true/false
(如果省略,则设置为true
)description
- 将作为参数描述设置的文本(如果省略,则设置为空字符串)
示例
@request name type
@request name type true
@request name type false Some description
对于多个参数,也可以采用不同的约定
@request
name type required description
name type required description
name type required description
如果您想将任意字符串作为请求/响应,可以在设置请求/响应参数时使用双引号。这样,将忽略所有其他参数,只返回双引号内的字符串。
示例
@response "example"
您可以在方法文档块中使用 @requestAppend key Class
或 @responseAppend key Class
包含额外的输入/输出模型,与原始模型一起。这将使用 key
作为键,将给定的 Class
属性附加到现有模型。
例如,如果原始模型 User
(具有属性 name、email),您想将 Post
模型(具有属性 title、description)作为输入列表附加到它。
@model User // <-- not needed if it is UserController or you already specified model on the controller
@requestAppend posts Post
这将导致以下请求
{
"name": "string"
"email": "string"
"posts": {
"title": "string"
"description": "string"
}
}
响应特定
默认情况下,在查看没有路径参数的 GET
请求时,响应将被标记为多个(表示集合输出,而不是单个模型)。
- 在方法文档块中包含
@multiple true/false
将覆盖这些默认值
如果变量类型是 array
,可以在括号内提供额外的属性(确保在类型和括号之间不留空格)来指示数组值的类型
@response attribute array[string] true Some description
即使在关联模型不存在的情况下,也可以直接将数据透视表附加到响应中。
@pivot table_name
例如,如果表格附加到了 User
模型,将返回以下响应
{
"name": "string"
"email": "string"
"pivot": {
"user_id": 0
"example_id": 0
}
}
缓存
数据库模型架构正在被缓存以提高性能(1天TTL),如果您修改了迁移文件,请确保运行 php artisan asseco:open-api --bust-cache
,这将强制重新缓存。
配置
使用 php artisan vendor:publish --provider="Asseco\OpenApi\OpenApiServiceProvider"
发布配置。
配置需要您最少程度的参与,但有些事情包无法假设。
- 对于
App
命名空间外的模型,请确保将完整命名空间包含在namespaces
配置键中,以便包能够自动获取模型属性。 - 对于不以模型命名的控制器(在
ModelController
格式中),请在controller_model_mapping
配置键中进行重映射。