devtools-marvellous / 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 auto-updated.
Last update: 2024-09-19 07:00:36 UTC
README
Laravel Sextant - 这是一个强大的、智能且简单的用于 Laravel 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 - 不需要参数,接受 true
或 false
,将 AND $key IS NULL
或 AND $key IS NOT NULL
添加到 SQL 查询字符串
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()
允许的关系。将名为 expand
的 $_GET 参数添加到请求中。注意:不允许的关系将被忽略。参数 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}', ...]]];
搜索
为了简短,添加了search
参数用于sql like
搜索。此参数与根模型和任何关联字段一起工作。
搜索示例
/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