phpsa / laravel-api-controller
一个基于Laravel的API基本控制器,将基本的CRUD映射到模型
Requires
- php: ^8.1
- laravel/framework: ^9.0|^10.0|^11.0
Requires (Dev)
- doctrine/dbal: >=2.3
- mockery/mockery: ^1.0
- nunomaduro/larastan: ^2.0
- orchestra/testbench: ^7.0|^8.0|^9.0
- phpunit/phpunit: ^9.5|^10.0
- dev-master
- v7.3.2
- v7.3.1
- v7.3.0
- v7.2.0
- v7.1.6
- v7.1.5
- v7.1.4
- v7.1.3
- v7.1.2
- v7.1.1
- v7.1.0
- v7.1.0-beta.1
- v7.0.2
- v7.0.1
- v7.0.0
- 6.x-dev
- v6.1.1
- V6.1.0
- V6.0.0
- 5.x-dev
- v5.9.6
- v5.9.5
- v5.9.4
- v5.9.3
- v5.9.2
- v5.9.1
- v5.9.0
- v5.8.4
- v5.8.3
- 5.8.3-b.2
- 5.8.3-b.1
- v5.8.2
- v5.8.1
- v5.8.0
- v5.7.0
- v5.6.1
- v5.6.0
- v5.5.1
- v5.5.0
- v5.4.1
- v5.4.0
- v5.3.1
- v5.3.0
- v5.2.0
- v5.1.0
- v5.0.0
- 5.0.0-alpha.2
- 5.0.0-alpha.1
- v4.3.0
- v4.2.3
- v4.2.2
- v4.2.1
- v4.2.0
- v4.1.1
- v4.1.0
- v4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- v4.0.0-beta.2
- v4.0.0-beta.1
- 3.x-dev
- 3.3.1
- v3.3.0
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.2.0-beta.4
- 3.2.0-beta.3
- 3.2.0-beta.2
- 3.2.0-beta.1
- v3.1.1
- v3.1.0
- v3.0.0
- 3.0.0-a.1
- 2.x-dev
- 2.5.0
- 2.4.0
- v2.3.0
- 2.2.1
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0.0
- 2.0.0-rc.1
- 2.0.0-b.3
- 2.0.0-b.2
- 2.0.0-b.1
- 2.0.0-a.1
- 1.x-dev
- 1.25.0-b.1
- 1.24.0
- 1.23.0
- 1.22.1
- 1.22.0
- 1.21.1
- 1.21.0
- 1.20.3
- 1.20.2
- 1.20.1
- 1.20.0
- 1.19.0
- 1.18.0
- 1.17.2
- 1.17.1
- 1.17.0
- 1.16.0
- 1.15.0
- 1.14.0
- 1.13.0
- 1.12.1
- 1.12.0
- 1.12.0-b2
- 1.12.0-b1
- 1.11.0
- 1.11.0-b.3
- 1.11.0-b.2
- 1.10.0
- 1.10.0-b1
- 1.9.1
- 1.9.0
- 1.9.0-b.2
- 1.9.0-b.1
- 1.8.0
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.0
- 1.6.0-b.1
- 1.5.0
- 1.5.0-rc.12
- 1.5.0-rc.11
- 1.5.0-rc.10
- 1.5.0-rc.9
- 1.5.0-rc.8
- 1.5.0-rc.7
- 1.5.0-rc.6
- 1.5.0-rc.5
- 1.5.0-rc.4
- 1.5.0-rc.3
- 1.5.0-rc.2
- 1.5.0-rc.1
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.2-b.2
- 1.4.2-b.1
- 1.4.1
- 1.4.0
- 1.3.1
- 1.3.0
- 1.2.1
- 1.2.0
- 1.1.1-rc.2
- 1.1.1-rc.1
- 1.1.0
- 1.1.0-rc.3
- 1.1.0-rc.2
- 1.1.0-rc.1
- 1.0.0
- 1.0.0-rc.2
- 1.0.0-rc.1
- 1.0.0-b.2
- 1.0.0-b.1
- 0.5.0-b.1
- 0.4.0
- 0.4.0-a.1
- 0.3.1
- 0.3.0
- 0.3.0-rc.1
- 0.2.1
- 0.2.0
- 0.2.0-rc.1
- 0.2.0-b.2
- 0.2.0-b.1
- 0.2.0-a.2
- 0.2.0-a.1
- 0.1.3
- 0.1.2
- 0.1.1
- 0.1.0
- dev-ricks_fixes
- dev-feat_request_validated_only
- dev-improve-relationships
- dev-release/5.x
- dev-fix/remove-tostring-calls-on-stringable
- dev-feat-query-parser-moved-to-trait
- dev-fix-non-relations
- dev-relationship_remap_documentation
- dev-add-restore-action-for-soft-deletes
- dev-relation_rempa_bakcup
- dev-josh-master-patch-92633
- dev-josh-master-patch-69646
- dev-105-user-model-and-namespace-in-policy-stub-is-hardcoded-for-query-functions
- dev-fix-inherits-bad-practice
- dev-104-minor-whitespace-issues-in-the-stub-files
- dev-fix_non-standard+route-binding
- dev-107-wrong-database-used-when-using-tenancy-for-laravel
- dev-98-handling-of-null-values-when-saving-related-data
- dev-103-make-api-model-causes-the-pivot-option-does-not-exist-message
- dev-feature/pass_resource_to_gates
- dev-101-differing-policy-paths
- dev-102-path-for-nested-controller-stub-is-incorrect
- dev-fix-child-models-always-returning-like-default
- dev-fix-nested-controller-stub-path
- dev-docs-update-readme
- dev-fix/map-related-on-array
- dev-beta
- dev-feature/gated_fields
- dev-feature/improved_cli_tools
- dev-analysis-AD4MMZ
- dev-parse-sync-fields-case
- dev-feature/pivot-values
- dev-feature/response_overiders
This package is auto-updated.
Last update: 2024-09-08 21:01:32 UTC
README
[[目录]]
默认可扩展的用于模型的基本CRUD API方法包括列表、显示、更新、添加和删除端点,用于与模型交互。
安装
通过composer安装
composer require phpsa/laravel-api-controller
发布配置文件(可选 - 如果您需要更改任何默认配置)
php artisan vendor:publish --provider="Phpsa\LaravelApiController\ServiceProvider" --tag="config"
使用方法
CLI命令
artisan make:api:controller {ControllerName}
生成控制器artisan make:api:policy {PolicyName} -m {Model}
生成策略文件artisan make:api:resource {ResourceName|CollectionName}
生成响应资源
这将为您创建一个Api/ModelNameController,并且您将具备以下基本路由
- GET
api/v1/{model_name}
- 列出所有/分页/过滤(类::index) - GET
api/v1/{model_name}/$id
- 显示指定ID(类::show) - POST
api/v1/{model_name}
- 插入新记录(类::store) - PUT
api/v1/{model_name}/$id
- 替换现有记录(类::update) - PATCH
api/v1/{model_name}/$id
- 更新现有记录(类::update) - DELETE
api/v1/{model_name}/$id
- 删除现有记录(类::destroy)
如果您在make:api:controller
上指定了--soft-deletes
选项,它还会创建一个额外的restore
控制器端点和路由
- PATCH
api/v1/{model_name}/$id
- 恢复软删除记录(类::restore)。这仅适用于启用了软删除的模型。
您可以通过简单地添加自己的方法来覆盖方法 - 上面的花括号中的方法名称
事件
- POST(类::store)- 触发一个新的
Phpsa\LaravelApiController\Events\Created
事件,该事件将新记录作为$record
提供 - PUT(类::update)- 触发一个新的
Phpsa\LaravelApiController\Events\Updated
事件,该事件将更新的记录作为$record
提供 - DELETE(类::destroy)- 触发一个新的
Phpsa\LaravelApiController\Events\Deleted
事件,该事件将删除的记录作为$record
提供
策略
策略:[https://laravel.net.cn/docs/6.x/authorization#generating-policies](https://laravel.net.cn/docs/6.x/authorization#generating-policies)
使用php artisan make:policy PostPolicy --model=Post
生成
- 获取列表 - 调用
viewAny
策略 - 获取单个 - 调用
view
策略 - 发布新内容 - 调用
create
策略 - 更新 - 调用
update
策略 - 删除项目 - 调用
delete
策略
策略中的查询/数据修改器用于API端点
qualifyCollectionQueryWithUser($user, $repository)
-> return void - 向存储库添加任何查询(例如 ->where('x',''))qualifyItemQueryWithUser($user, $repository)
-> return void - 向存储库添加任何查询(例如 ->where('x',''))qualifyStoreDataWithUser($data)
- 返回更新的数据数组qualifyUpdateDataWithUser($data)
- 返回更新的数据数组
资源/集合(转换)
资源:[https://laravel.net.cn/docs/6.x/eloquent-resources](https://laravel.net.cn/docs/6.x/eloquent-resources)
使用php artisan make:apiresource UserResource
和php artisan make:api:resource UserCollection
生成
更改资源以扩展
使用 Phpsa\LaravelApiController\Http\Resources\ApiResource
作为你的资源,使用 Phpsa\LaravelApiController\Http\Resources\ApiCollection
作为你的资源集合
在你的控制器中覆盖以下参数
protected $resourceSingle = UserResource::class; protected $resourceCollection = UserCollection::class;
蛇形命名法 vs 驼峰命名法
- 将所有驼峰命名法转换为蛇形命名法的中间件:
Phpsa\LaravelApiController\Http\Middleware\SnakeCaseInputs
- 设置请求头
X-Accept-Case-Type
为snake
或camel
以更改你的数据响应
过滤
稳定的选项,一旦实验稳定后将删除
对于 get 命令,你可以使用以下 URL 模式进行过滤
包含 / 不包含
你可以向过滤器传递一个值数组,例如: filter[user_id]=1||2||||4||7
或 filter[user_id!]=55||33
空 / 非空(从 1.23.0 版本引入)
如果你需要过滤字段是否为空或非空,可以使用自 1.23.0 版本以来的过滤器参数。例如: filter[age]=NULL
或 filter[age!]=NULL
。注意,NULL 必须为大写。
旧版本 在你的模型中添加一个作用域:例如
public function scopeAgeNull(Builder $builder, $isNull = true){ $isNull ? $builder->whereNull('age') : $builder->whereNotNull('age'); }
添加到你的 allowedScopes,然后在 URL 中调用它,例如 ?ageNull=1
用于 where null 和 ?ageNull=0
用于 where age not null
过滤
- 使用 URL 模式
filters[column][operator]=value
例如filters[age][>]=18&filters[title][contains]=testing
-
空 =
filters[age]=NULL
将生成where age is null
-
JSON 列 =
filters[meta->seo][is]=enabled
将生成
where json_unquote(json_extract(`meta\`, '$."seo"')) = 'enabled'
- 关系:
filters[relationName][has]
或filters[relationName][!has]
或filters[relation_name][not_has]
- 关系过滤
filters[tags][has][slug]=my_slug
- 关系
filters[tags]=true
或filters['tags.slug']=myslug
filters[tags.slug][!]=myslug
filters[tags.slug][!][contains]=money
在控制器上强制作用域/查询过滤器覆盖
protected function getNewQuery(): Builder
{
return resolve($this->model())->newQuery();
}
方法在你的控制器中包含任何额外的查询/作用域等。
请求
我们添加了一个请求宏,以便您可以根据需要设置这些内容
例如
public function index(Request $request) { $request->apiFilter('user_id', auth()->id()); $request->apiFilter('owner_id', 'not_equals', auth()->id()); $request->apiFilter('age', '>=', 5); $request->apiFilter('age', '<=', 10); $request->apiInclude(['owner','user']); $request->apiAddFields(['x','y','z']);
- 过滤方法为
apiFilter($column, $value)
或apiFilter($column, $operator, $value)
- 添加字段方法为
apiAddFields(array|string $fieldsOrAttributesToInclude)
- 包含方法为
apiInclude(array|string $relations)
在你的控制器中,我们通常使用 request->all()
来填充模型。如果你希望使用更严格的选项,可以选择仅在控制器中调用 $this->setOnlyValidated()
来仅使用验证过的值,这将使用 request->validated()
来获取数据(注意:这意味着它将不会从 postValidation 中获取任何合并的信息)。
作用域
除了过滤之外,您还可以使用 Laravel 的 Eloquent 查询作用域 来执行更复杂的搜索或过滤。只需将 $allowedScopes
添加到您的 ApiResource
中,该作用域就会作为查询参数公开。
假设你在你的 Eloquent 模型上定义了一个 scopeFullname
,你可以按照以下方式将其公开到 API 中
protected static $allowedScopes = [ 'fullname' ];
给定上述 $allowedScopes
数组,你的 API 用户现在可以请求 ?fullname=John
。查询参数值将传递到你的 Eloquent 模型的作用域函数中。
过滤相关模型
你可以轻松地使用配置了 include
的任何相关模型进行过滤。只需在查询字符串中指定 ?filter[model.field]=123
即可。相同的过滤选项也适用于相关字段。
分组过滤作用域
filter_by_relation_group[a][name]=weight&filter_by_relation_group[a][value][>]=900&filter_by_relation_group[b][name]=color&filter_by_relation_group[b][value]=color
public function scopeFilterByRelationGroup(Builder $builder, array $wheres): void
{
$where = collect($wheres)->map(fn ($child) =>
$this->parseFiltersArray($child)
)->each(
fn($group, $key) => $builder->whereHas('Relation', function ($subQ) use ($group, $key) {
$group->each(
fn($filter, $column) => collect($filter)->each(fn($value, $comparison) => $this->buildQuery($column, $comparison, $value, $subQ))
);
}
)
);
}
字段、关系、排序 & 分页
字段
默认情况下返回所有字段,你可以通过以下方式限制到特定字段
- API 控制器参数
$defaultFields
默认为protected $defaultFields = ['*'];
- 切换到包含字段数组 - URL 查询字符串中的 fields 参数:例如
fields=id,name,age
= 只返回这些,这将覆盖上述内容。 - 在你的响应资源中,你可以设置 static::allowedFields 来锁定可返回的字段。
- 这还控制了哪些相关资源可以被返回。包括在
$mapResources
中使用的键(见下文“关系”)。
- 这还控制了哪些相关资源可以被返回。包括在
- URL查询字符串中的
addfields
和removefields
参数将与这些一起工作。 - 使用laravel eloquent模型
$appends
属性来自动包含自定义属性访问器。
门控响应字段
可以通过定义 $gatedFields
来使用门控控制对字段和相关资源的访问。
protected static array $fieldGates = [
'gate-one' => [
'fieldA',
'fieldB',
],
'gate-two' => [
'fieldA',
'fieldC,
'relatedResourceD'
]
];
每个指定的门控都将用来确定是否包含那一组字段。
每个门控都会传递资源和用户,因此它可以测试用户是否应该被允许访问那个特定的资源。
示例门控定义
Gate::define(
'supervises-the-group',
fn ($user, Group $group) => (int) $user->id === $group->supervisor_id
);
关系
- 使用在您的模型中定义的关系,您可以通过逗号分隔的列表传递,例如
include=join1,join2
,这将返回那些连接(一个或多个)。
只需在您的 Resource
中添加一个 protected static $mapResources
,以定义要分配相关数据的资源。例如,对于一对多关系,应指定一个集合,而对于一对一关系,则直接指定相关资源。这将允许API正确格式化相关记录。
protected static $mapResources = [
'notes' => NotesCollection::class,
'owner' => OwnerResource::class
];
- 您可以为大多数类型的关系自动更新和创建相关记录。只需在您的POST或PUT请求中包含相关资源名称即可。
- 重要:如果您在资源中使用
$defaultFields
和/或$allowedFields
,则$mapResources
中的相关资源键也必须包含在这些列表中,以便包含该相关资源。
对于 BelongsToMany
或 MorphToMany
关系,您可以选择同步策略。默认情况下,这将采用 添加 策略。也就是说,发送的关联记录将被添加到任何现有的相关记录中。在每次请求的基础上,您可以选择 同步 策略,这将删除请求中未列出的任何相关记录的枢纽。注意实际的相关记录不会被删除,只是枢纽条目。
要选择 同步 行为,请将请求中的 ?sync[field]=true
设置为。
排序
- 排序也可以作为逗号列表传递,例如
sort=age asc
或sort=age asc,name desc,eyes
- 分别生成sort age asc
和sort age asc, name desc, eyes asc
的SQL。 - 默认排序也可以通过在控制器中重写
protected $defaultSort = null;
参数来添加。
分页
- 可以通过在控制器中重写
protected $defaultLimit = 25;
来启用/禁用分页。 - 分页也可以通过URL使用
limit=xx&page=y
来传递。 - 分页也可以通过重写
protected $maximumLimit = false;
参数来限制每页的最大数量。
验证
- 在发布新记录时,可以通过向控制器添加一个
rulesForCreate
方法来执行验证,该方法返回一个数组,例如
[ 'email' => 'required|email', 'games' => 'required|numeric', ]
请参阅 https://laravel.net.cn/docs/5.8/validation#conditionally-adding-rules
- 对于更新记录,按上述方法添加一个方法
rulesForUpdate
。
默认值
以下参数在Base Api控制器中设置,并且可以在特定情况下被您的控制器重写
protected $resourceSingle = JsonResource::class;
用于单个资源的集合protected $resourceCollection = ResourceCollection::class;
用于资源集合的集合protected $defaultFields = ['*'];
默认字段以响应protected $defaultSort = null;
设置查询的默认排序。protected $defaultLimit = 25;
如果未指定,则一次显示的项目数量。 (0 = 最大限制)protected $maximumLimit = 0;
可以通过 $_GET['limit'] 设置的最大限制。 - 这与默认限制相关联,如果想要禁用分页,则两者都应为0。 ) 将允许在一次调用中返回所有记录。protected $unguard = false;
在创建/更新之前需要取消对模型的保护吗?
作用域
软删除记录
将 Phpsa\LaravelApiController\Model\Scopes\WithSoftDeletes
特性添加到您的模型中,添加到您的资源文件中
class MyModelResource extends ApiResource { protected static $allowedScopes = [ 'withTrashed', 'onlyTrashed' ];
现在可以在查询中附加 withTrashed=1
或 onlyTrashed=1
。
响应
可以通过覆盖以下受保护的方 法来覆盖每个点的响应
- handleIndexResponse
- handleStoreResponse
- handleShowResponse
- handleUpdateResponse
- handleDestroyResponse
性能提示
缓存表列定义
– 在 https://github.com/phpsa/laravel-api-controller/pull/118/files 中引入 – 添加了缓存表定义的能力,以减少获取表列的调用次数,可以在配置文件中启用或设置 PHPSA_API_CACHE_TABLE_COLUMNS
变量为 true。
原始分页获取
– handleIndexAction 将使用完整的 Eloquent 模型,handleIndexActionRaw 将绕过 Eloquent 并使用来自数据库的原始响应。
安全
如果您发现任何与安全相关的问题,请通过电子邮件而不是使用问题跟踪器来报告。