Gautier Deleglise 刚刚发布了 Laravel Rest Api 3.0,这是对原包的重新构建,该包允许你通过单个资源类将 Eloquent 模型转换为 REST API。我们曾在 2023 年首次介绍它,后来在添加 Laravel Scout 支持时再次报道。版本 3.0 保留了相同的理念,并替换了其底层的大部分实现。

主要亮点包括:

  • 用于驱动过滤器、验证、响应值和 API 文档的强类型字段
  • 通过 Scramble 生成 OpenAPI 文档
  • 提供计数、趋势、分区、进度和表格的指标端点
  • 使用 428 响应和签名令牌对操作和批量写入进行确认

强类型字段

在 2.x 版本中,资源列出列名。而在 3.0 中,资源声明带有 Text、Integer、Number、Date、Enum、Json 等类型的字段:

public function fields(): array
{
    return [
        ID::make('id'),
        Text::make('title')->rules('max:80')->creationRules('required'),
        Integer::make('seats')->rules('min:0'),
        Enum::make('status', ShowStatus::class)->offered([ShowStatus::Planned, ShowStatus::OnSale]),
        Date::make('starts_on')->creationRules('required'),
    ];
}

该包利用这一声明处理 API 的其余部分:

  • 过滤器仅接受符合字段类型的运算符。其他任何内容都会返回 422。
  • 写入操作会根据字段的规则进行验证,错误会指向具体失败的键,例如 mutate.0.attributes.seats。
  • 响应以原始类型返回值,因此数字返回为数字,空的 JSON 字段返回为 {}。
  • Enum::offered() 限制了客户端可以写入的枚举情况。在上例中,已撤回的状态仍然可以在旧行中读取和过滤,但没有人能再次设置它。

通过 Scramble 生成 OpenAPI 文档

内置的文档生成器已被移除。版本 3.0 改为集成 Scramble。安装 Scramble 后,/docs/api 将记录每个资源的每个端点,包含每个资源的 typed body、每个字段的规则、请求示例和错误响应。

该包自己的测试套件会将这些请求示例发送到 API,并根据生成的文档验证每个响应。如果文档与 API 不一致,测试将失败。

指标

指标是 3.0 版本新增的功能。你在资源上声明一个指标,它就会获得一个独立的端点,无需编写控制器代码。以下是一个按状态统计演出的分区示例:

class ShowsByStatus extends Partition
{
    public function calculate(Builder $query): PartitionResult
    {
        return $this->count($query, 'status');
    }
}

该端点返回每个组及其计数:

{"data": {"type": "partition", "parts": [{"key": "planned", "label": "planned", "value": 2}, {"key": "sold_out", "label": "sold_out", "value": 1}], "other": null}}

Value、Trend、Partition、Progress 和 Table 指标类型涵盖计数、总和、平均值、中位数和百分位数。它们还支持日期范围、时区、与上一时期的比较以及结果缓存。指标仅计算当前用户有权查看的行数,客户端可以使用与搜索相同的过滤器进一步缩小范围。

确认机制

操作、修改、删除、恢复或强制删除现在可以在运行前要求用户确认。这对于批量取消和删除非常有用:

public function destroyConfirmation(Collection $models): ?Confirmation
{
    return Confirmation::make("Delete {$models->count()} shows and their tickets?");
}

端点将返回 428 状态码、你的消息和一个签名令牌。当客户端使用该令牌发送相同的请求时,操作才会执行。此过程不涉及会话,也不需要调用额外的端点。

其他变更

  • Policies 会在请求到达的每个资源以及写入的每一行上运行,且在第一次写入发生之前。perimeterQuery() 在每个搜索层级的每个资源上将其限定为租户或团队。
  • 单次写入可以在一个事务中创建、更新、附加、同步和删除子行。response 块返回写入的行,而标记为 versioned() 的资源在客户端读取后行发生变化时会返回 409。
  • 操作可以按每次运行、每个分块或每行在一个事务中运行,并支持报告进度的队列分块和批处理。
  • Rest::search() 可在 HTTP 之外重放保存的搜索,使作业或导出遵循与 API 相同的规则和策略。
  • 文本搜索支持 LIKE、MySQL、MariaDB 或 PostgreSQL 全文索引,或通过 Scout 支持 Meilisearch、Typesense 和 Algolia。
  • 所有面向客户端的消息均提供英文和法文版本,并遵循请求的本地化语言。
  • php artisan rest:quick-start 读取你的表并生成资源、控制器、入门级策略和路由。php artisan rest:check 可在 CI 中捕获缺失的策略或边界条件。
  • 该包附带了 Laravel Boost 技能,以便你的 AI 助手能够按照该包期望的方式编写资源。

升级说明

Laravel Rest Api 3.0 需要 PHP 8.3+ 和 Laravel 13.30+。基于 Laravel 12 的应用程序应保持在 2.x 版本。

composer require lomkit/laravel-rest-api:^3.0

版本 3.0 在整个包中存在破坏性变更,升级指南将逐区域详细介绍每一项变更。