mapi / easyapi
该包使构建API变得简单。
Requires
- php: >=7.0
- laravel/framework: >=7.04
README
此包提供了一种简单的方式来构建REST API,以受控且具有一定动态性的方式提供基本功能。
这些基本功能包括
- 分页。
- 排序。
- 搜索。
- 基于列的筛选。
安装
composer require mapi/easyapi
工作原理
此包依赖于继承和特性来向Eloquent模型添加作用域。这些作用域提供了前面提到的基本功能。它还提供了一个表单请求,以便更容易地使用这些功能。
提供的模型描述
- 要在Eloquent模型中使用它,模型应继承以下类之一
ApiModel
:此类用于应扩展Illuminate\Database\Eloquent\Model
类的模型。ApiPivot
:此类用于应扩展Illuminate\Database\Eloquent\Relations\Pivot
类的模型。ApiUser
:此用于应扩展Illuminate\Foundation\Auth\User
的用户类。
- 如果您的类已经从另一个类继承,则应使用提供的特性
IsApiModel
:此特性提供了与先前模型相同的功能,但它需要对模型的行为进行特殊处理。
- 此步骤是可选的,取决于您的应用程序。我们提供了一个基础表单请求
BaseRequest
,在其中我们定义了分页、排序和搜索的验证规则。
如何使用
我们将通过代码示例展示如何实现每个功能。
分页
我们已经在名为getData
的作用域中实现了此功能。此作用域使用由Laravel框架提供的paginate
函数。它还允许检索所有数据和数据的精简版本。
PS:页面编号应通过请求中的键名page传递
- 获取分页数据
这可以通过传递一个包含具有键number
的关联数组来完成,其值表示每页要检索的记录数。 - 获取所有数据
要获取所有数据,应在请求中发送等于-1的number参数number = -1
。 - 获取精简数据此功能允许开发人员控制模型应检索哪些字段。在某些情况下,例如填充下拉列表,您可能需要两个字段。一个表示值
id
,例如,另一个表示显示给用户的文本:name
,例如。要实现此功能,有两个步骤
首先,覆盖模型中$listColumnsToRetrieve
属性。其值应为应调用此功能时检索的列名数组。
其次,要告诉作用域加载结果的最简版本,您应在传递给作用域的数据数组中发送一个键名为list
的键,其值为true
。
// Inside your model (MyModel)
class MyModel extends ApiModel {
protected $listColumnsToRetrieve = [
'id','name'
];
}
// Where you need to retrieve the data (in controller for example)
$data = [
'list' => 1,
'number' => 10
];
MyModel::query()->getData($data);`
排序
我们已在名为 sort
的范围内实现了此功能。此范围使用 Laravel 框架提供的 orderBy
和 orderByDesc
函数。目前,排序支持对一列进行排序。默认情况下,用户可以基于所有列进行排序。为了限制允许排序的列,可以声明一个名为 $allowedColumnsToSortBy
的变量。其值应该是用户允许排序的列名数组。客户端可以通过发送名为 sort
的参数来请求按列名进行排序,它是一个表示列名的字符串,以及名为 sort_desc
的布尔值,表示排序方向是否为降序。
// Inside your model (MyModel)
class MyModel extends ApiModel {
protected $allowedColumnsToSortBy = [
'id','name'
];
}
// Where you need to sort the data (in controller for example)
$data = [
'sort' => 'column_name',
'sort_desc' => 1
];
MyModel::query()->sort($data);`
搜索
我们已在名为 search
的范围内实现了此功能。此范围使用 where like
在模型的直接列或关联列中搜索特定列。默认情况下,不允许对任何列进行搜索。为了在 直接列
上激活此功能,需要在模型中定义一个名为 $allowedColumnsToSearch
的变量。其值应该是搜索过程将应用到的列名数组。为了在 关联列
上激活此功能,需要在模型中定义一个名为 $allowedRelationsToSearch
的变量。其值是一个关联数组。键代表 关联名称
,值是应该在该表中搜索的列名数组。客户端可以使用名为 search
的参数使用搜索功能,系统将自动搜索模型中定义的直接列和关联列。
// Inside your model (MyModel)
class MyModel extends ApiModel {
protected $allowedColumnsToSearch = [
'id','name
];
protected $allowedRelationsToSearch = [
'relation_name_1' => [ 'id','name' ],
'relation_name_2' => [ 'name','price' ]
];
}
// Where you need to sort the data (in controller for example)
$data = [
'search' => 'search string',
];
MyModel::query()->search($data);`
过滤
我们已在名为 filter
的范围内实现了此功能。此范围支持不同类型的过滤。支持的类型包括
直接过滤类型
- where_.
- or_where_.
- whereIn_.
- whereNotIn_.
- whereLike_.
- or_whereLike_.
- whereNull_.
- whereNotNull_.
- or_whereNull_.
- or_whereNotNull_.
关联过滤类型
- where_relation_.
- or_where_relation_.
- whereIn_relation_.
- whereNotIn_relation_.
- whereLike_relation_.
- or_whereLike_relation_.
- or_whereNull_relation_.
- or_whereNotNull_relation_.
- whereNull_relation_.
- whereNotNull_relation_.
这些过滤器适用于模型的直接列或关联的列。为了在 直接列
上激活此功能,需要在模型中定义一个名为 $allowedFilters
的变量。其值应该是客户端允许基于其进行过滤的列名数组。为了在 关联列
上激活此功能,需要在模型中定义一个名为 $allowedRelationsFilters
的变量。其值应该是一个关联数组。键是我们需要过滤的 关联名称
,值是客户端允许基于其进行过滤的列名数组。在定义了允许过滤的列之后,客户端可以通过发送列名作为参数来使用过滤器,该参数前缀为 直接过滤器类型
之一(针对直接列)或 关联过滤器类型
之一(针对关联列)。
// Inside your model (MyModel)
class MyModel extends ApiModel {
protected $allowedFilters = [
'id','name
];
protected $allowedRelationsFilters = [
'relation_name_1' => [ 'id','name' ],
'relation_name_2' => [ 'name','price' ]
];
}
// Where you need to sort the data (in controller for example)
$data = [
'where_name' => 'name 1',
'where_relation_price' => 500
];
MyModel::query()->filter($data);`
加载关联
我们已经在名为loadRelations
的作用域中实现了这个功能。这个作用域允许客户端请求服务器加载关系,而无需在服务器端创建多个API。一个API可以服务于客户端的不同用例。为了激活这个功能,您应该在模型中定义一个名为$allowedRelationsToLoad
的变量。它的值应该是一个关联数组。它的key
代表关系名称。它的value
应该是我们需要加载的关系列
的数组。您可以使用*
来表示您想要加载所有列。
注意:
当您定义要加载的列的子集时,外键列应该是这些值之一,否则关系将为空。客户端可以通过发送一个表示需要加载的关系名称
的参数来使用这个功能,该参数以with_
为前缀,其值是一个布尔值,表示关系是否需要。
// Inside your model (MyModel)
class MyModel extends ApiModel {
protected $allowedRelationsToLoad = [
'relation_name_1' => [ 'id','name' ],
'relation_name_2' => [ 'id','name','price' ]
];
}
// Where you need to sort the data (in controller for example)
$data = [
'with_relation_name_1' => 0,
'with_relation_name_2' => 1
];
MyModel::query()->loadRelations($data);`
应用所有功能
如果您想使用所有功能,可以使用applyAllFilters
作用域并传递客户端发送的输入。