yu-renery / sextant
Laravel Sextant 引擎
Requires
- doctrine/dbal: ^3.5
- laravel/framework: >=5.8
Requires (Dev)
- orchestra/testbench: ~3.8
- phpunit/phpunit: ^8.0
This package is not auto-updated.
Last update: 2024-10-01 03:03:17 UTC
README
Laravel Sextant - 这是一款强大、智能且简单的 API 调用过滤引擎。
能力概述
安装
- 将以下代码添加到
composer.json
"repositories": [ { "url": "https://git.attractgroup.com/amondar/sextant.git", "type": "git" } ] "require": { "amondar/sextant": "^1.0.7" }
- 发布配置
php artisan vendor:publish --provider="Amondar\Sextant\SextantServiceProvider"
基础
在模型中使用 HasSextantOperations
特性。如果需要使一些关系在 API 调用中公开可用,请重新声明 extraFields()
函数。以下是一个示例
class SomeModel extends Model { use HasSextantOperations; ... public function extraFields() { return ['someRelation']; } ... public function someRelation() { return $this->hasOne(SomeRelation::class); } }
默认情况下,使用 sextant 特性后,它将连接到模型作为作用域操作。因此,您可以像以下这样调用它
public function index(Request $request) { return SomeModel::withSextant($request)->get() }
过滤使用
您必须使用名为 filter
的 $_GET
参数与模型过滤进行交互。过滤参数期望包含参数的 JSON 字符串。
可用操作
isNull - 不需要参数,accept
真值或 false
,向 SQL 查询字符串添加 AND $key IS NULL
或 AND $key IS NOT NULL
operation - 逻辑操作标识符,接受 '>','<','>=','<=','<>','not in','in','like'
value - 示例值,可以是数组,如果使用 "operation":"in"
或 "operation":"not in"
from 和 to - 范围过滤操作。可以独立工作。如果接收日期,则通过 Carbon::parse()
函数处理并转换为 mysql 格式。对于过滤,我们使用 >=
和 <=
,因此范围包括起始值和结束值。在不允许操作 <=
和 >=
的情况下,您可以使用自己的过滤。例如 - {"from": { "value": "123","operation":">"}}
。
注意:对于简单的等于查询,使用简单的表示法 - {"id":1}
,则查询将看起来像 WHERE id = 1
。
查询示例
/message?filter={"created_at":{"from":"2016-02-20","to":"2016-02-24 23:59:59"}, "id":{"operation":"not in", "value":[2,3,4]}} /message?filter={"id":{"from":2,"to":5}} /message?filter={"id":{"to":5}} и /message?filter={"id":{"operation":"<=","value":5}} - эквивалентны /message?filter={"updated_at":{"isNull":true}} /message?filter={"answer":{"operation":"like","value":"Partial search string"}} - will be converted into: WHERE answer LIKE "%Partial search string%" /message?filter={"answer":"Full search string"} - точный поиск по строке
通过关系存在筛选模型
/users?filter={"posts":{"operation":"has", "value":3, "condition":">"}} - find users with minimum 3 posts. Condition can be - <,>,=,<> and combinations. /users?filter={"posts":{"operation":"doesnthave"}} - find users without posts.
通过关系筛选
/message?filter={"user.name":"asd"}
您必须在 extraFields
函数中定义允许的关系。使用与根模型中的简单字段相同的关联过滤器。
筛选关系
您可以通过使用 $_GET
参数 filterExpand
来筛选关系。它的工作方式与简单过滤器相同,但筛选关系数据。
public function index(Request $request) { return SomeModel::withSextant($request, [], ['except' => ['expand' => ['someExpandName']]])->get(); } public function index(Request $request) { return SomeModel::withSextant($request, [], ['only' => ['expand' => ['someAnotherExpandName']]])->get(); }
之后,如果您在请求中发送任何筛选操作或排序,或扩展,则将跳过给定的关系。注意:'only' 限制也适用于空数组 - ['only' => ['expand' => []]]
- 将禁止在给定请求上对它们进行任何扩展和筛选操作。
排序
您可以通过任何模型或关系字段对数据进行排序。要使用排序,只需定义名为 sort
的 $_GET
参数。Sextant 默认按 asc
排序,如果您需要 desc
排序,您需要在排序定义前缀中添加减号。例如 - -views_count
排序示例
/message?sort=id /message?sort=-id /message?sort=user.name
您可以使用逗号分隔多个排序。例如 -?sort=user.first_name,user.last_name
关系排序
您可以对关系进行排序。使用 $_GET
参数 sortExpand
。它的工作方式与根模型上的简单排序相同,但排序关系数据。
关系扩展
您可以请求关系扩展。您只能请求通过 extraFields()
允许的关系。将 $_GET
参数 expand
添加到请求中。注意:不允许的关系将被忽略。参数 expand
对于 filterExpand
和 sortExpand
操作是必需的。
扩展示例
/message?expand=user
###响应示例
{ "id": 1, "message": "some message", "user_id": 1, "user": { "id": 1, "name": "Some username" } }
限制
从1.1.4版本开始,您可以为过滤操作提供限制。例如,我们有一个目标,在CRUD的索引方法中禁用一些扩展,以达到速度的全防护,那么我们可以使用限制
['only' => ['expand' => ['{EXPAND_NAME}', ...]]];
搜索
添加了用于简短sql like
搜索的search
参数。此参数与根模型和任何关系字段一起使用。
搜索示例
/message?search={"query":"some","fields":"relation1.field|table_field|relation2.field"}
Laravel作用域的使用。
在Sextant中,您可以使用原生Laravel作用域功能。与作用域一起工作就像过滤一样简单。
/message?filter={"answer":{"operation":"scope","value":"someScopeName"}} - without params /message?filter={"answer":{"operation":"scope","value":"someScopeName","parameters":["some", "params for ", "scope input"]}} - with params /message?filter={"answer":{"operation":"scope","value":"someScopeName","parameters":"one param"}} - with one param /message?filter={"owner.first_name":{"operation":"scope","value":"someRelationScopeName","parameters":"Some name"}} - on relation usage.
注意:
如果与关系一起工作,则作用域必须在关系模型中存在。您只需将其连接到请求即可。如下所示
/posts?scopes='[{"name":"someScopeName","parameters":[]}]'
当使用scopes
指令时,必须传递parameters
键,即使parameters
为空。为了保护模型作用域免受不允许的请求,请使用extraScopes()
函数。例如
class SomeModel extends Model { use HasSextantOperations; ... public function extraScopes() { return ['someScopeName']; } ... public function scopeSomeScopeName($query) { $query->... } }
!!!注意:使用作用域进行公开世界会带来很多保护问题。您可以创建orWhere
查询等,这将破坏您的搜索保护。为了避免这种情况
class SomeModel extends Model { public function scopeSomeScopeName($query) { $query->where('some_field', 'search') ->where(function($query){ $query->where('field', 'some search) ->orWhere('field', 'some other search'); }) } }
此代码将转换为SQL
SELECT * FROM `messages` WHERE `some_field` = 'search' AND (`field` = 'some search' OR `field` = 'some other search')
原始使用
您可以在不调用模型或在不使用Sextant操作特质的情况下使用Sextant。例如
app('sextant')->filtrate(User::class, $request, $predefinedParameters); \\or Sextant::filtrate(User::class, $request, $predefinedParameters);
如你所见,你可以在模型类上使用过滤。如果模型没有Sextant操作,我们将使用我们的默认模型,我们将将其转换为你的模型
$newModel = new SextantModel(); $newModel->setTable($model->getTable()); $newModel->setKeyName($model->getKeyName()); $newModel->setKeyType($model->getKeyType()); return $newModel->withSextant($request, $params);
注意:默认模型具有空的extraFields
和extraScopes
。 注意:您可以通过将第三个参数传递给->withSextant(...)
函数来预先定义过滤参数。只需将参数作为数组传递。示例
app('sextant')->filtrate(User::class, $request, ['sort' => '-created_at', 'filter' => ['posts.views_count' => ['operation' => '>=', 'value' => 10]]]); \\or Sextant::filtrate(User::class, $request, ['sort' => '-created_at', 'filter' => ['posts.views_count' => ['operation' => '>=', 'value' => 10]]]);
扩展
您可以为Sextant引擎创建自己的扩展。只需将新操作添加到配置中。注意:
每个新操作都必须实现Amondar\Sextant\Contracts\SextantActionContract::class