optimus / laravel-controller
Requires
- laravel/framework: ~6.0|~7.0|~8.0|~9.0|~10.0
- optimus/architect: 2.0.*
Requires (Dev)
- mockery/mockery: 1.3.*
- orchestra/testbench: 4.*
- php-coveralls/php-coveralls: 2.2.*
- phpunit/phpunit: ~8.0
This package is auto-updated.
Last update: 2023-12-28 14:50:10 UTC
README
简介
一个Laravel基础控制器类和一个特性,它可以使您向资源URL添加过滤、排序、预加载和分页。
献给乔尔达诺·布鲁诺
此包以我的英雄乔尔达诺·布鲁诺命名。一个真正的先知,敢于梦想超出被认为可能的事物。由于他的思想和拒绝放弃这些思想,他在1600年被活活烧死。我强烈推荐这个由Neil deGrasse Tyson讲述的关于他生活的短动画片。
功能
- 解析GET参数,用于动态预加载相关资源、排序和分页
- 使用过滤器组进行高级资源过滤
- 使用Optimus\Architect进行相关资源的侧加载、ID加载或嵌入式加载
- ... 欢迎在此处提出新功能的想法
教程
要开始使用Bruno,我强烈推荐我的关于Laravel API中的资源控制的文章。
安装
对于Laravel 5.3及以下版本
composer require optimus/bruno ~2.0
对于Laravel 5.4及以上版本
composer require optimus/bruno ~3.0
使用
以下示例将使用一个假设的资源端点 /books,该端点将返回一个属于 Author 的 Book 集合。
Book n ----- 1 Author
可用的查询参数
| 键 | 类型 | 描述 |
|---|---|---|
| 包括 | 数组 | 要加载的相关资源数组,例如 ['author', 'publisher', 'publisher.books'] |
| 排序 | 数组 | 排序属性,例如 'title' |
| 限制 | 整数 | 返回的资源限制 |
| 页面 | 整数 | 与限制一起使用 |
| 过滤器组 | 数组 | 过滤器组数组。请参阅以下语法。 |
实现
<?php namespace App\Http\Controllers; use Optimus\Api\Controller\EloquentBuilderTrait; use Optimus\Api\Controller\LaravelController; use App\Models\Book; class BookController extends LaravelController { use EloquentBuilderTrait; public function getBooks() { // Parse the resource options given by GET parameters $resourceOptions = $this->parseResourceOptions(); // Start a new query for books using Eloquent query builder // (This would normally live somewhere else, e.g. in a Repository) $query = Book::query(); $this->applyResourceOptions($query, $resourceOptions); $books = $query->get(); // Parse the data using Optimus\Architect $parsedData = $this->parseData($books, $resourceOptions, 'books'); // Create JSON response of parsed data return $this->response($parsedData); } }
语法文档
预加载
简单预加载
/books?includes[]=author
将返回一个包含预加载的 Author 的 5 个 Book 集合。
ID模式
/books?includes[]=author:ids
将返回一个包含 Book 的集合,并预加载它们的 Author ID。
侧加载模式
/books?includes[]=author:sideload
将返回一个 Book 集合和一个在根作用域中预加载的 Author 集合。
有关预加载类型的更多信息,请参阅Optimus\Architect的README。
分页
有两大参数可供选择: limit 和 page。 limit 将决定每页的记录数,而 page 将决定当前页。
/books?limit=10&page=3
将返回第30至40本书。
排序
应定义为排序规则的数组。它们将按照定义的顺序应用。
排序规则
| 属性 | 值类型 | 描述 |
|---|---|---|
| key | 字符串 | 用于排序的模型属性 |
| direction | ASC 或 DESC | 按何种方向对属性进行排序 |
示例
[
{
"key": "title",
"direction": "ASC"
}, {
"key": "year",
"direction": "DESC"
}
]
这将导致书籍按标题升序排序,然后按年份降序排序。
过滤
应定义为过滤组的数组。
过滤组
| 属性 | 值类型 | 描述 |
|---|---|---|
| 或 | 布尔值 | 此组中的过滤器是否应通过逻辑 OR 或 AND 运算符分组 |
| filters | 数组 | 过滤器数组(见下文语法) |
过滤器
| 属性 | 值类型 | 描述 |
|---|---|---|
| key | 字符串 | 要过滤的模型属性(也可以是自定义过滤器) |
| value | 混合类型 | 要搜索的值 |
| operator | 字符串 | 要使用的过滤器运算符(见下文不同类型) |
| not | 布尔值 | 否定过滤器 |
运算符
| 类型 | 描述 | 示例 |
|---|---|---|
| ct | 字符串包含 | ior 匹配 Giordano Bruno 和 Giovanni |
| sw | 以...开头 | Gior 匹配 Giordano Bruno 但不匹配 Giovanni |
| ew | 以...结尾 | uno 匹配 Giordano Bruno 但不匹配 Giovanni |
| eq | 等于 | Giordano Bruno 匹配 Giordano Bruno 但不匹配 Bruno |
| gt | 大于 | 1548 匹配 1600 但不匹配 1400 |
| gte | 大于等于 | 1548 匹配 1548 和以上(仅适用于 Laravel 5.4 及以上版本) |
| lte | 小于等于 | 1600 匹配 1600 和以下(仅适用于 Laravel 5.4 及以上版本) |
| lt | 小于 | 1600 匹配 1548 但不匹配 1700 |
| in | 在数组中 | ['Giordano', 'Bruno'] 匹配 Giordano 和 Bruno 但不匹配 Giovanni |
| bt | 介于 | [1, 10] 匹配 5 和 7 但不匹配 11 |
特殊值
| 值 | 描述 |
|---|---|
| null (字符串) | 将检查属性是否为 NULL 值 |
| (空字符串) | 将检查属性是否为 NULL 值 |
自定义过滤器
记得我们的关系 Books n ----- 1 Author。想象一下你想通过 Author 名称过滤书籍。
[
{
"filters": [
{
"key": "author",
"value": "Optimus",
"operator": "sw"
}
]
}
]
现在这都没问题,然而由于它是一个关系,我们的模型中没有 author 属性。这会导致错误,因为 Eloquent 会尝试在不存在 author 属性上使用 where 子句。我们可以通过实现自定义过滤器来修复这个问题。在任何使用 EloquentBuilderTrait 的地方实现一个名为 filterAuthor 的函数
public function filterAuthor(Builder $query, $method, $clauseOperator, $value) { // if clauseOperator is idential to false, // we are using a specific SQL method in its place (e.g. `in`, `between`) if ($clauseOperator === false) { call_user_func([$query, $method], 'authors.name', $value); } else { call_user_func([$query, $method], 'authors.name', $clauseOperator, $value); } }
注意:需要注意的是,自定义过滤器将寻找与属性同名的关系。例如,如果尝试为名为 author 的属性使用自定义过滤器,Bruno 将尝试从 Book 模型中预加载 author 关系。
自定义过滤器函数
| 参数 | 描述 |
|---|---|
| $query | Eloquent 查询构建器 |
| $method | 要使用的 where 方法(where,orWhere,whereIn,orWhereIn 等) |
| $clauseOperator | 操作符可用于非精确查询(如 !=、=、> 等)。 |
| $value | 过滤器值 |
| $in | 布尔值,表示是否为数组内过滤 |
示例
[
{
"or": true,
"filters": [
{
"key": "author",
"value": "Optimus",
"operator": "sw"
},
{
"key": "author",
"value": "Prime",
"operator": "ew"
}
]
}
]
作者姓名以 Optimus 开头或以 Prime 结尾的书籍。
[
{
"filters": [
{
"key": "author",
"value": "Brian",
"operator": "sw"
}
]
},
{
"filters": [
{
"key": "year",
"value": 1990,
"operator": "gt"
},
{
"key": "year",
"value": 2000,
"operator": "lt"
}
]
}
]
作者姓名以 Brian 开头,且出版年份在 1990 年到 2000 年之间的书籍。
可选的简写过滤语法(简写)
过滤器可以可选地使用简写表示,它将给定的过滤器数组[key, operator, value, not(optional)] 在评估时构建为详细的过滤器数组。
例如,这个过滤器组(详细)
[
{
"or": false,
"filters": [
{
"key": "author",
"value": "Optimus",
"operator": "sw"
},
{
"key": "author",
"value": "Prime",
"operator": "ew"
}
{
"key": "deleted_at",
"value": null,
"operator": "eq",
"not": true
}
]
}
]
可以这样表示(简写)
[
{
"or": false,
"filters": [
["author", "sw", "Optimus"],
["author", "ew", "Prime"],
["deleted_at", "eq", null, true]
]
}
]
标准
此包符合 PSR-1、PSR-2 和 PSR-4。如果您发现符合标准的问题,请通过拉取请求发送补丁。
测试
$ phpunit
贡献
有关详细信息,请参阅 CONTRIBUTING。
许可
MIT 许可证(MIT)。有关更多信息,请参阅 许可文件。