matthenning/eloquent-api-filter 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

matthenning/eloquent-api-filter

Composer 安装命令:

composer require matthenning/eloquent-api-filter

包简介

Awesome and simple way to filter Eloquent queries right from the API URL without the clutter.

README 文档

README

Eloquent API Filter

Awesome and simple way to create, query and modify Eloquent models through your API - with only a few lines of code.


Concept

When developing API applications, you'll often end up with lots of duplicate code within your controllers. Eloquent API Filter offers a simple way to expose your models through the API by defining a route and a tiny controller. Your controller only needs to use a few traits and you'll have a full CRUD implementation for your model exposed through you API.


Table of Contents

Installation

Package installation

composer require matthenning/eloquent-api-filter

Controller setup

You have the choice to use either of the following methods to leverage the filter. The easiest method out of the box is to simply extend the included controller.

Option 1: Extend the controller (recommended)

The easiest way to use the Eloquent API Filter is to extend its controller. For this example, let's say you have a model named Person. You'll just have to create a matching controller and use the included traits to enable the default methods for index, show, store, update, destroy:

use Matthenning\EloquentApiFilter\Controller;

class PersonController extends Controller
{
    use UsesDefaultIndexMethodTrait,
        UsesDefaultShowMethodTrait,
        UsesDefaultStoreMethodTrait,
        UsesDefaultUpdateMethodTrait,
        UsesDefaultDestroyMethodTrait;

} 

Next you can expose your controller by adding a new route:

Route::resource('persons', \App\Http\Controllers\PersonController::class);

Eloquent API Filter will automatically find the matching model class as long as you follow the naming scheme of this example. If you have custom names or namespaces, you can override the modelName property within your controller:

protected ?string $modelName = Person::class;

And you're done! Start querying your API following the method guidelines. See https://laravel.com/docs/10.x/controllers#actions-handled-by-resource-controller for actions store, show, index, update, destroy:

POST /api/persons
{
    "name": "Alexander",
    "age": 23
}

GET /api/persons/1

GET /api/persons/?filter[age]=23

PUT /api/persons/1
{
    "age": 24
}

DELETE /api/persons/1

Custom Resource

If you're using custom resources (https://laravel.com/docs/master/eloquent-resources) you can define a resourceName property on your models. Otherwise the default resource will be used. Make sure to override the toArray and call enrich() with your data. The enrich method will make sure all eager loaded relations (/model?with[]=relation1,relation2) are also transformed by their respective resource.

In your Person model:

public static ?string $resourceName = PersonResource::class;

In your PersonResource:

class PersonResource extends \Matthenning\EloquentApiFilter\Resource
{

    public function toArray(Request $request): array
    {
        return $this->enrich([
            'id' => $this->resource->id,
            // ... map your fields here
        ]);
    }

}

Option 2: Use the trait

If you'd like to handle the controller and resource logic yourself entirely, can use the FiltersEloquentApi trait in your controller.

class PersonController extends Matthenning\EloquentApiFilter\Controller
{  
    
    use Matthenning\EloquentApiFilter\Traits\FiltersEloquentApi;
    
    public function index(Request $request)
    {
        $persons = Person::query();
        
        return $this->filterApiRequest($request, $persons);
    }
}

Option 3: Query the filter directly

If traits are not to your taste you can also initialize Eloquent API Filter yourself.

use Matthenning\EloquentApiFilter\EloquentApiFilter;

class PersonController extends Controller
{    
    public function index(Request $request)
    {
        $query = Person::query();
        
        $filtered = (new EloquentApiFilter($request, $query))->filter();
        
        return $filtered->get();
    }
}


Queries

Filtering

URL Syntax

Filter with specific operator:

GET /model?filter[field]=operator:comparison

Filter for equality:

GET /model?filter[field]=operator

Operators:

  • eq (equal, can be omitted)
  • ne (not equal)
  • ge (greater or equal)
  • gt (greater)
  • le (lower or equal)
  • lt (lower)
  • in (expects a comma separated array as value)
  • notin (expects a comma separated array as value)
  • null
  • notnull,
  • like
  • notlike
  • today (for timestamps)
  • nottoday (for timestamps)

Examples

Matches all entities where name starts with Rob and deceased is null:

GET /persons?filter[name]=like:Rob*&filter[deceased]=null:

Multiple filters on one field can be chained. Matches all entities where created_at is between 2016-12-10 and 2016-12-08:

GET /persons?filter[created_at]=lt:2016-12-10:and:gt:2016-12-08`

Filter by related models' fields by using the dot-notaion. Matches all Posts of Persons where Post name contains "API"

GET /persons?filter[posts.name]=like:*API*

Get all persons with name Rob and Bob

GET /persons?filter[name]=in:Rob,Bob

Special filters

Timestamps

Matches all persons whos' birthdays are today

GET /persons?filter[birthday]=today

Sorting

URL Syntax

GET /model?orderBy[field]=direction

Examples

Limit and sorting. Matches the top 10 persons with age of 21 or older sorted by name in ascending order

GET /persons?filter[age]=ge:21&order[name]=asc&limit=10

Select fields

Select only specific columns. Might need additional work on your model transformation.

URL Syntax

GET /model?select=column1,column2

Examples

GET /persons?select=name,email

Joins

URL Syntax

GET /model?with[]=relation1
GET /model?with[]=relation1&filter[relation1.field]=operator:comparison

Examples

Join posts-relation on persons

GET /persons?with[]=posts

Complex filter values

If you need to filter for a value with special characters, you can base64 encode the field to avoid breaking the filter syntax.

URL Syntax

GET /model?filter[field]={{b64(value)}}

Examples

GET /model?filter[field]=lt:{{b64(MjAxNy0wNy0yMiAyMzo1OTo1OQ==)}}


Responses

Responses always contain two JSON objects data and meta. Data contains the queried models and meta contains for example pagination details.

Example

{
    "meta": {
        "pagination": {
            "items": 10,
            "total_items": 113,
            "total_pages": 12,
            "current_page": 1,
            "per_page": 10
        }
    },
    "data": [
        {
            "id": 1,
            "name": "Alexander",
            "age": 23
        },
        { /*...*/ }, { /*...*/ }
    ]
}


What if I need more?

In case you need complex queries which are not covered by this library, you can use the EloquentApiFilter trait in your custom controller and further filter the query before retrieving the models. That way you can still use the filter features and only need to add your custom filtering before returning the retrieved models.

matthenning/eloquent-api-filter 适用场景与选型建议

matthenning/eloquent-api-filter 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4.9k 次下载、GitHub Stars 达 10, 最近一次更新时间为 2017 年 04 月 05 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「api」 「filter」 「laravel」 「eloquent」 「filtering」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 matthenning/eloquent-api-filter 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 matthenning/eloquent-api-filter 我们能提供哪些服务?
定制开发 / 二次开发

基于 matthenning/eloquent-api-filter 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 4.9k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 10
  • 点击次数: 7
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 10
  • Watchers: 1
  • Forks: 3
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-3.0
  • 更新时间: 2017-04-05