devtools-marvellous / rest-actions
Amondar Rest Actions
Requires
- laravel/framework: >=5.5.0
README
有任何问题,请通过电子邮件联系 - yurenery@gmail.com
!!!!!! 仅适用于 Laravel >= 5.5+
能力表
安装
"repositories": [ { "url": "https://git.attractgroup.com/amondar/RestActions.git", "type": "git" }, { "url": "https://git.attractgroup.com/amondar/sextant.git", "type": "git" }, { "url": "https://git.attractgroup.com/amondar/model-remember.git", "type": "git" } ]
"amondar/rest-actions": "^4.2", "amondar/sextant": "^1.1",
连接
为了正确使用该包的所有功能,建议安装以下包:
将 **RestActions** 特性连接到控制器。请注意,控制器中必须存在 **public function serverFunction** 函数。
abstract class CoreController extends Controller { use RestActions; ... public function serverResponse() { return (new ServerResponse()); } }
ServerResponse 类与任何项目直接兼容,不会随当前特性一起提供。由于每个项目和对API的响应特性不同,示例实现可以在本仓库找到。所需函数用于包装该类
status - Функция для установки статуса в ответ.
resource - Функция для передачи данных в ответ. Принимает на вход параметр Resource:class instance или просто массив.
extend - Функция необходимая для расширения стандартных данных в ответе, если такие необходимы.
使用示例
class CategoryController extends CoreController { use IndexAction, ShowAction, StoreAction, UpdateAction, DestroyAction; protected $actions = [ 'index' => [ 'request' => CategoryRequest::class, 'view' => 'backend.categories.index', ], 'show' => [ 'request' => CategoryRequest::class, ], 'store' => [ 'request' => CategoryRequest::class, ], 'update' => [ 'request' => CategoryRequest::class, 'parameters' => [ 'category' => Category::class ] ], 'destroy' => [ 'request' => CategoryRequest::class, ] ]; /** * UserController constructor. * * @param CategoryRepository $repository */ public function __construct(CategoryRepository $repository) { $this->repository = $repository; } }
处理 Nemesis 过滤和排序
为了将参数传递给过滤器,请使用键 - conditions
'index' => [ 'request' => CourseRequest::class, 'view' => '', 'ajaxTransform' => false, 'conditions' => [ 'limit' => 20, ], ],
对于计算,有一个唯一的参数,可以在请求中添加 limit=count 并在响应中获得简单的数量。例如,使用这种方法处理通知计数非常方便。
无仓库使用
如果要无仓库使用,请指定变量 modelClass 以指定当前控制器中工作的模型类的名称。
protected $modelCAlss = SubCategory::calss;
通过仓库使用
通常,当通过仓库工作时,特性会寻找在仓库中与控制器中函数同名函数。然而,在某些实现中这并不方便。为了在仓库内部重写函数
'update' => [ 'request' => CategoryRequest::class, 'repository' => 'someOtherUpdateFunctionName' ],
从 URL 传递参数到仓库方法
为了将参数传递给仓库,只需在仓库方法中指定所需参数即可,但这有一些细微差别。标准参数传递示例
'update' => [ 'request' => CategoryRequest::class, 'parameters' => [ 'category' => Category::class // ключ массива в точности повторяет ключ из урла. Для правильности ввода воспользоваться php artisan route:list. ] ],
仓库中的函数
public function update(Repository $repository, Category $category)
如果仓库中的参数具有不同的类名,例如在继承中,则可以按其名称传递参数
'update' => [ 'request' => CategoryRequest::class, 'parameters' => [ // ключ массива parameters в точности повторяет ключ из урла. Для правильности ввода воспользоваться php artisan route:list. 'category' => ['class' => Category::class, 'parameter_name' => 'vocabulariable'], ] ],
仓库中的函数
public function update(Repository $repository, Vocabulariable $vocabulariable);
特性将自动确定所需参数并将它们传递给仓库。请求将指定请求,然后是来自 parameters 数组的参数。重要:也可以使用参数来处理多用途函数。例如
public function update(Repository $repository, Category $category, $someParam = false);
在上面的示例中,需要将参数 $someParams=true 传递给函数,但它在 URL 和路由请求中都没有
'update' => [ 'request' => CategoryRequest::class, 'parameters' => [ 'category' => Category::class, // ключ в точности повторяет ключ из урла. Для правильности ввода воспользоваться php artisan route:list. 'someParam' => true ] ],
此外,如果您的仓库类实现了用于安装模型和返回模型的 setModel 和 model 方法,则可以在仓库中不传递模型参数,特性将尝试从仓库中安装模型,如果能在路由中找到它。
处理视图
某些特性函数可以加载视图。目前,有 2(两个)个函数与视图一起工作 - index 和 show。为了指定处理器使用必要的视图
'index' => [ 'request' => CategoryRequest::class, 'view' => 'backend.categories.index', ],
请注意,对于 index 视图,将可用对象 $data,其中包含从数据库中选择的数据。在 show 方法中,这是模型名称的小写蛇形变量。例如,SubCategory 转换为 - $sub_category。还有一个扩展所有视图数据的功能,例如用于构建和显示菜单数据
/** * TODO redeclare to add default data for all views. * * @return array */ protected function restDefaultData() { return []; }
细节和扩展
为了与上述包一起工作,已编写用于限制选择和扩展响应的函数。函数 index & show。重写下面的函数以更改过滤器和响应视图的工作方式。关键字 parameters 是用于过滤器的参数数组
/** * Return index additional parameters to filter. * * TODO Redeclare this function in controller to make request a little bit secure for example. * * @param Request $request * @param Router $router * * @return array */ protected function getIndexFilterParameters(Request $request, Router $router) { return [ //'parameters' => $this->getActionConditions($router)->toArray(), - Стандартное использование, достает параметры из массива $actions. 'parameters' => [ 'filter' => [ 'sub_category.category_id' => 1 ] ], ]; } /** * Extend index response. * * TODO redeclare this function in controller and return extended information. * * @param Request $request * @param Router $router * * @return array */ protected function extendIndexResponse(Request $request, Router $router) { return [ ]; } // ДЛЯ SHOW ФУНКЦИИ /** * Return index additional parameters to filter. * * TODO Redeclare this function in controller to make request a little bit secure for example. * * @param Request $request * @param Router $router * * @return array */ protected function getShowFilterParameters(Request $request, Router $router) { return [ 'parameters' => $this->getActionConditions($router)->toArray(), ]; } /** * Extend index response. * * TODO redeclare this function in controller and return extended information. * * @param Request $request * @param Router $router * * @return array */ protected function extendShowResponse(Request $request, Router $router) { return [ ]; }
如果您的路由器模型使用的是id以外的任何其他参数,请在模型内部重写Laravel的标准模型函数 - getRouteKeyName。
/** * Return route key name. * * @return string */ public function getRouteKeyName() { return 'uri'; }
许多人会在他们的路由中使用绑定,但对于交易来说这相当困难。为了限制正在工作的模型绑定的范围,重写以下函数并添加您自己的限制。该函数在所有需要处理当前设置模型和从路由中提取参数的功能中都会使用。
/** * Return model for actions. * * TODO redeclare this function and append more secure db request if needed. * * @param $id * * @return mixed */ protected function getModelForActions($id, Model $model, Request $request) { // Check if we receive current REST model. if($model->is($this->restMakeModel())){ $query = $this->getBaseFilterQuery($request); }else{ $query = $model->newQuery(); } return $query->where($model->getRouteKeyName(), $id)->firstOrFail(); }
对于其他类型的请求,如索引 & 显示 & 更新 & 删除,可以重写函数 getBaseFilterQuery。
/** * Return base query builder. * * @param $actionName - name of the action from actions array. * @param Request $request * * @return \Illuminate\Database\Eloquent\Builder */ protected function getBaseFilterQuery(Request $request) { return $this->restMakeModel()->newQuery(); }
如你所见,该函数接受当前操作的名称作为输入,因此可以为任何操作创建任何基本查询,包括创建、更新和删除。
控制器继承
在直接继承的情况下,可能会出现需要添加缺失的动作的情况。为了不重复整个 actions
数组
/** * Return extended actions. * * @param Router $router * * @return array */ public function getActions(Router $router) { $actions = parent::getActions($router); // parent - Расширяемый контроллер. return array_merge($actions, [ 'store' => [ 'request' => CampaignRequest::class, 'transformer' => CampaignResource::class, ], ]); }
getActions
方法在调用所需方法时仅被调用一次。别忘了连接到扩展方法。
通常,在继承过程中,我们的验证请求会发生变化。因此,增加了一个变量 - restActionsRequest
示例
class UserController extends CoreController { use IndexAction; /** * Main request class. * * @var string */ protected $restActionsRequest = UserRequest::class; /** * Possible actions. * * @var array */ protected $actions = [ 'index' => [ 'onlyAjax' => true, 'transformer' => UserResource::class, ], ]; /** * UserController constructor. * * @param UserRepository $repository */ public function __construct(UserRepository $repository) { $this->repository = $repository; } } class PostOwnerController extends UserController { /** * Main request class. * * @var string */ protected $restActionsRequest = PostOwnerRequest::class; /** * PostOwnerRepository constructor. * * @param PostOwnerRepository $repository */ public function __construct(PostOwnerRepository $repository) { parent::__construct($repository); } /** * Return base filter builder. * * @param $actionName * * @return \Illuminate\Database\Eloquent\Builder */ protected function getBaseFilterQuery(Request $request) { return $this->repository->newQuery()->hasPermission([ Permission::CAN_OWN_POST ]); } }
重要:在上面的示例中,存储库必须是父控制器存储库的子类。
通过在其他控制器中创建控制器实例进行扩展
对于index & show函数,可以提供额外的配置转换。例如,您需要创建控制器实例,从数据库中选择数据,但以某种方式更改响应,使其符合您的要求。在这种情况下,您可以使用键 - ajaxTransform
'index' => [ 'request' => CourseRequest::class, 'view' => '', 'ajaxTransform' => false, 'conditions' => [ 'limit' => 20, ], ],
$response = app(CourseController::class)->index($router); if($response instanceof Collection){ //return response for filter and change it //or render spesific view with collectioned data or transform it for your self. } //return view return $response;
同样,可以在调用操作之前设置所需操作的可变参数
app(CourseController::class) ->setActionView('index', 'frontend.filter.sub_category') ->setActionRepositoryMethod('index', 'newMethodName') ->setActionConditions('index', [ 'limit' => 20 ]) ->setActionParameters('index', [ 'course' => SubCategory::class ]) ->index($router);
缓存
缓存在每个索引和显示动作的选择中都是可用的 - index, show。
'index' => [ 'request' => CourseRequest::class, 'cache' => [ 'time' => 120, // in secs 'tags' => 'courses_list' // tag is not available on all cache drivers, but always required field. ] ],
有任何问题,请通过电子邮件联系 - yurenery@gmail.com
动作管理
控制器中指定的任何动作都会扩展这些参数
[ 'request' => Request::class, 'model' => null, 'view' => null, 'conditions' => [], 'transformer' => Resource::class, 'ajaxTransform' => true, 'simpleView' => false, 'onlyAjax' => false, 'onlyBrowser' => false, 'cache' => [ 'time' => false, 'tag' => null ], 'protectedLimit' => self::$PROTECTED_LIMIT, ]
描述
- request - 用于验证请求的请求
- model - 用于处理请求的模型的重写。 NULL - 如果指定了存储库或定义了全局模型。
- view - 请允许将其发送到前端的视图(根据blade规则),它需要在不需要json的请求上返回
- conditions - 额外的静态过滤参数
- transformer - 用于特定操作的转换器类参数。如果没有指定,则使用toArray。
- ajaxTransform - 确定是否调用转换器以获取有关该方法的响应信息。如果指定为false - 使用toArray()。
- simpleView - 确定是否仅在请求html页面时加载html页面,而无需连接到数据库和过滤器。data = collection([])。
- onlyAjax - 确定是否仅在工作请求json数据和使用相应的headers时工作。
- onlyBrowser - 确定是否仅在请求html页面时工作。
- cache - 缓存参数数组。参见上文。
- protectedLimit - 重写单次选择的最大可能数据量限制的参数。作为从数据库中选择大量数据(无分页)时的服务器挂起的保护。也可以通过重写全局变量 protected static $PROTECTED_LIMIT 来设置全局限制,默认 = 100条记录;
- sextantRestrictions - Sextant限制集成。要获取更详细的信息,请参阅Sextant过滤器文档的相关部分。