morningtrain / laravel-resources
Laravel 的资源系统
Requires
- php: ^7.4|^8.0|^8.1
- illuminate/auth: ^7.0|^8.0|^9.0|^10.0
- illuminate/console: ^7.0|^8.0|^9.0|^10.0
- illuminate/contracts: ^7.0|^8.0|^9.0|^10.0
- illuminate/database: ^7.0|^8.0|^9.0|^10.0
- illuminate/http: ^7.0|^8.0|^9.0|^10.0
- illuminate/routing: ^7.0|^8.0|^9.0|^10.0
- illuminate/support: ^7.0|^8.0|^9.0|^10.0
- laravel/ui: ^2.0|^3.0|^4.0
- morningtrain/laravel-context: ^2.0|^3.0
- morningtrain/laravel-fields: ^1.0
- morningtrain/laravel-filters: ^1.0|^2.0
- morningtrain/laravel-support: ^1.0
- dev-master
- 4.x-dev
- 4.25.0
- 4.24.0
- 4.23.0
- 4.22.1
- 4.22.0
- 4.21.5
- 4.21.4
- 4.21.3
- 4.21.2
- 4.21.1
- 4.21.0
- 4.20.0
- 4.19.1
- 4.19.0
- 4.18.0
- 4.17.1
- 4.17.0
- 4.16.0
- 4.15.0
- 4.14.1
- 4.14.0
- 4.13.0
- 4.12.0
- 4.11.1
- 4.11.0
- 4.10.0
- 4.9.0
- 4.8.0
- 4.7.2
- 4.7.1
- 4.7.0
- 4.6.1
- 4.6.0
- 4.5.0
- 4.4.0
- 4.3.0
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.0
- 4.0.0
- 3.x-dev
- 3.1.1
- 3.1.0
- 3.0.0
- 2.x-dev
- 2.12.0
- 2.11.1
- 2.11.0
- 2.10.0
- 2.9.2
- 2.9.1
- 2.9.0
- 2.8.0
- 2.7.1
- 2.7.0
- 2.6.4
- 2.6.3
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0.0
- 1.4.0
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.28
- 1.2.27
- 1.2.26
- 1.2.25
- 1.2.24
- 1.2.23
- 1.2.22
- 1.2.21
- 1.2.20
- 1.2.19
- 1.2.18
- 1.2.17
- 1.2.16
- 1.2.15
- 1.2.14
- 1.2.13
- 1.2.12
- 1.2.11
- 1.2.10
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.1
- 1.2.0
- 1.1.10
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1
- 1.0.1
- 1.0
This package is auto-updated.
Last update: 2024-09-08 07:57:50 UTC
README
操作是一组在服务器上执行的动作,从设置路由到处理客户端请求的所有逻辑。
一个简单的操作可以是获取所有用户并返回给客户端的索引操作。
另一个用例可能是触发 Eloquent 模型上的动作。在这种情况下,用户输入总是需要验证,获取模型,执行方法,然后可能返回一些对用户有意义的响应。
这类似于一个简单的操作,我们需要返回模型的单个实例给用户(传统的读取调用)——但它包含一些额外的逻辑来处理方法执行。
删除操作类似,它首先获取模型并触发删除方法。
安装
通过 Composer
$ composer require morningtrain/laravel-resources
$ php artisan vendor:publish --provider="MorningTrain\Laravel\Resources\LaravelResourcesServiceProvider"
配置
在 config/resources.php 中注册您的资源和操作
第一级键对应于命名空间,值是资源类的数组。您可以使用数组键为资源提供自定义名称,并嵌套资源数组。只需确保所有项目都具有唯一的键。
如果为资源未提供键,则使用 Str::snake(class_basename($resource))。这意味着如果您的类名为 User,并且同一命名空间中存在具有键 "user" 的另一个资源,它们将发生冲突。
示例
'api' => [ \App\Operations\Api\User::class, 'custom_user' => \App\Operations\Api\User::class, 'nested' => [ \App\Operations\Api\User::class, 'custom_user' => \App\Operations\Api\User::class, 'deep_nested' => [ \App\Operations\Api\User::class, 'custom_user' => \App\Operations\Api\User::class, ], /* * These two will not work together - non-unique resource name: * \App\Operations\Api\MyResource::class, * 'my_resource' => \App\Operations\Api\User::class, */ ],
示例
索引操作
索引操作的目的在于检索模型条目的列表并将其作为 JSON 返回。
以下代码示例来自包,将说明如何实现索引操作。
<?php namespace MorningTrain\Laravel\Resources\Operations\Eloquent; use MorningTrain\Laravel\Resources\Support\Contracts\EloquentOperation; use MorningTrain\Laravel\Resources\Support\Pipes\Eloquent\QueryToCollection; use MorningTrain\Laravel\Resources\Support\Pipes\Eloquent\QueryModel; use MorningTrain\Laravel\Resources\Support\Pipes\TransformToView; class Index extends EloquentOperation { const ROUTE_METHOD = 'get'; protected function beforePipes() { return [ /** * Takes filters and model name as parameters and returns a new query object */ QueryModel::create()->model($this->model)->filters($this->getCachedFilters()), /** * Trigger `get` on the query and returns the resulting collection */ QueryToCollection::create(), /** * Transform the collection by applying any appends to each model in the entry */ TransformToView::create()->appends($this->appends, $this->overwrite_appends), ]; } }
在项目层面,索引类可以是资源或单个操作实现的。
以下示例是一个实现单个索引操作的 EloquentResource。操作已在基类中添加,因此不需要静态 $operations 属性。
在我们的示例中,用户被返回,并应用了分页过滤器。
<?php namespace App\Http\Operations\Api; use MorningTrain\Laravel\Resources\Support\Contracts\EloquentResource; use MorningTrain\Laravel\Resources\Operations\Eloquent\Index; use MorningTrain\Laravel\Filters\Filter; use App\Models\User as Model; class Users extends EloquentResource { protected $model = Model::class; public static $operations = [ Index::class, ]; public function getFilters(){ return [ Filter::paginate(), ]; } }
以下示例类似于上面的示例,但操作将作为一个单独的类实现。
<?php namespace App\Http\Operations\Api\Users; use MorningTrain\Laravel\Resources\Operations\Eloquent\Index as Operation; use MorningTrain\Laravel\Filters\Filter; use App\Models\User as Model; class IndexUsers extends Operation { protected $model = Model::class; public function getFilters(){ return [ Filter::paginate(), ]; } }
设计原则
我们用操作完成的大部分工作都可以使用传统的 MVC 方法实现。然而,控制器逻辑很容易退化成重复和结构不良的代码。
我们实现设置中的 操作 的目标是大大提高代码的重用性。当我们找到了解决特定任务的良好解决方案时,为什么不将其用于所有类似任务呢?
资源
在这个上下文中,我们所说的 资源 实质上是一组操作。每个操作都在资源内部初始化和配置。
配置
操作的可配置性意味着我们可以构建一个多用途的操作,它在类似情况下使用,但具有略微不同的行为。
一个常见的例子可能是典型的索引操作,根据一组过滤器查询 Eloquent 模型并返回一个集合给用户。
在这种情况下,我们的索引操作被配置为使用特定的模型类(所有 Eloquent 操作都是这样)和过滤器数组。
到目前为止,我们只提到了API操作,但一个操作也可以是一个正常的页面请求。在这种情况下,它会配置一个更美观的路径,例如返回一个特定的视图。在我们的大多数用例中,页面操作渲染的视图会输出一个期望的React组件。
所有操作都应该配置为通过权限层进行保护,以控制访问。使用Laravel,我们最终利用底层的策略和门控系统来控制访问。我们还使用额外的权限Laravel包来创建所需的模型和数据库结构,以支持角色和权限。
使用管道执行微任务
随着我们Laravel包2.x版本的发布,操作的主要逻辑被分割成多个更小的任务,以便允许进一步的代码重用。这是通过使用Laravel管道设置来实现的,这些设置也用于Laravel内部处理中间件。
有关Laravel 5.7中管道的文档,请参阅此处。
这允许在类似操作之间实现更高的定制程度,同时保持基本逻辑解耦。
每个小任务都被称为管道,以反映它是操作管道的一部分。
管道的示例
- 验证:使用Laravel兼容的验证规则验证传入的HTTP请求
- 过滤查询:允许基于HTTP请求变量过滤数据库查询构建器实例。
- 准备响应负载:将主操作逻辑的返回值统一转换为负载JSON对象。
将操作结构化为管道也使实际的代码/逻辑不包含在操作中。剩下的基本上是一个可配置的类。要更改和调整操作的工作方式,只需要复制/扩展操作和管道的更改。在大多数情况下,不需要添加额外的代码。
管道
TriggerOnModel
TriggerOnModel管道期望前一个管道返回的数据是一个Eloquent模型。它将在模型或提供的闭包上触发一个方法,并使用当前模型实例。
可以使用以下方式使用它
\MorningTrain\Laravel\Resources\Support\Pipes\Eloquent\TriggerOnModel::create() ->trigger('someModelMethod')
或者使用闭包的方式如下
\MorningTrain\Laravel\Resources\Support\Pipes\Eloquent\TriggerOnModel::create() ->trigger( fn(Model $model) => $model->someModelMethod() )
Action Eloquent操作基本上是一个带有TriggerOnModel管道的读取操作。
TriggerOnModelsInCollection
TriggerOnModelsInCollection管道类似于TriggerOnModel。它期望一个模型集合,并为集合中的每个模型实例执行触发器。
QueryToCollection
触发前一个管道返回的查询的get操作,并返回结果。
QueryToModel
触发前一个管道返回的查询的first操作,并返回结果。
QueryToCount
触发前一个管道返回的查询的count操作,并返回结果。
ToResourceView
它期望前一个管道返回一个模型或集合实例。数据(模型或集合)将被传递到一个Laravel资源,并返回结果数组。
\MorningTrain\Laravel\Resources\Support\Pipes\ToResourceView::create() ->view(MyResourceView::class)
大多数Eloquent操作已经配置为使用此管道,因此可以像这样配置资源
public function readOperation(Read $read) { $read->model(MyModel::class) ->resourceView(MyModelResource::class); }
SetEnv
此管道设置上下文环境变量。它可以通过environment方法进行配置。
\MorningTrain\Laravel\Resources\Support\Pipes\Context\SetEnv::create() ->environment(['env' => 'variable'])
environment方法是对Context::env的代理,这意味着它还可以接受一个在生成ENV时执行的闭包。
BladeView
BladeView管道返回与配置匹配的blade视图。
\MorningTrain\Laravel\Resources\Support\Pipes\Pages\BladeView::create() ->path('path.to.blade.view') ->parameters(['blade' => 'parameters'])
RespondWithPageEnv
RespondWithPageEnv 管道将当前 Context 中的 ENV 作为响应返回,如果是一个 AJAX 请求。可以通过调用其路由使用 Ajax 来获取页面的 ENV。
\MorningTrain\Laravel\Resources\Support\Pipes\Pages\RespondWithPageEnv::create()
致谢
此包由 Morningtrain 开发并积极维护。
_- _ -__ - -- _ _ - --- __ ----- _ --_
( Morningtrain, Denmark )
`---__- --__ _ --- _ -- ___ - - _ --_ ´
o
. ____
_||__| | ______ ______ ______
( | | | | | | |
/-()---() ~ ()--() ~ ()--() ~ ()--()
--------------------------------------