asseco-voice/laravel-open-api

Laravel OpenAPI 生成器

v3.0.0 2023-08-08 08:15 UTC

This package is auto-updated.

Last update: 2024-09-08 11:23:21 UTC


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 模型表属性,没有 idcreated_atupdated_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 配置键中进行重映射。