Laravel Sextant 引擎

v1.3.5 2024-09-19 06:59 UTC

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 - 不需要参数,接受 truefalse,将 AND $key IS NULLAND $key IS NOT NULL 添加到 SQL 查询字符串

operation - 逻辑操作标识符,接受 '>','<','>=','<=','<>','not in','in','like'

value - 示例值,可以是数组,如果使用 "operation":"in""operation":"not in"

fromto - 范围过滤操作。可以独立工作。如果提供了范围,则通过 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 对于 filterExpandsortExpand 操作是必需的。

展开示例

  /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);

注意:默认模型具有空的extraFieldsextraScopes注意:您可以通过将第三个参数传递到->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