alcidesrh / laravel-generic-resource
通用的或不可知性的Laravel资源及其CRUD(创建、读取、更新、删除)操作。
Requires
- php: ^7.0|^8.0
README
基本用法
use Alcidesrh\Generic\GenericResource; $user = User::find(1); // It will only return the id and name fields. return new GenericResource( $user, ['id', 'name']);
此包可以帮助您返回数据,而不必为每个模型创建Resource或ResourceCollection,从而作为传统的Laravel资源。
要求
-Laravel >= 5
-php >= 7.0
安装
composer require alcidesrh/laravel-generic-resource
与嵌套或相关模型一起工作
假设User类有一个类型为User类的父属性,以及一个与自身相关的belongsTo
关系。同时还有一个与Product类的belongsToMany
关系。所以$user->parent
返回User类的一个实例,而$user->products
是一个Product类实例的集合。
假设我们只想获取具有以下字段的用户列表:id、name、parent(仅父的id和name字段)和产品列表(仅产品的id、name和价格字段)。我们可以这样获取这些数据
use Alcidesrh\Generic\GenericResource; $user = User::find(1); return new GenericResource( $user, [ 'id', 'name', 'parent' => ['id', 'name'], 'products' => ['id', 'name', 'price'] ]);
您可以根据关系允许的嵌套级别添加许多嵌套层
... 'products' => [ 'id', 'name', 'price', 'order' => [ 'id', 'created_at', 'company' => [ 'id', 'name' ] ] ]
注意:为了返回嵌套关系数据,必须通过模型的外观进行查询。
// this will work new GenericResource( User::find(1), ['id', 'name'] ); // this will work new GenericResource( User::find(1), ['id', 'name', 'parent' => ['id', 'name']] ); // this will work new GenericResource( DB::table('users')->where('id', 1)->first(), ['id', 'name'] ) // this won't new GenericResource( DB::table('users')->where('id', 1)->first(), [ 'id', 'name', 'parent' => ['id', 'name'] // it can not be access the parent property since the object retrieved is an stdClass type ] );
注意
- 如果未提供第二个参数(要获取的字段数组),则将返回模型的所有字段。
- 如果要返回的字段中有一个不存在于模型中,它将在结果数组中省略。
GenericResourceCollection
use Alcidesrh\Generic\GenericResourceCollection; $users = User::where('active', 1); // it will return a collection of user with only the id and name fields. return new GenericResourceCollection( $users->paginate( $perPage ), ['id', 'name']); //you can pass nested property as well as in the GenericResource return new GenericResourceCollection( $users->paginate( $perPage ), [ 'id', 'name', 'parent' => ['id', 'name'], 'products' => ['id', 'name', 'price'] ]);
注意:根据官方Laravel的Api Resources文档的指南线,GenericResource
和GenericResourceCollection
类被制作出来,并添加了一些额外的代码以使其通用。因此,您可以期望具有相同的结构和行为。
GenericController
此包的主要目标是提供GenericResource
和GenericResourceCollection
。然而,此包还提供了一个GenericController
,可以用于获取不需要复杂查询或转换的数据,并仅返回请求的字段或所有字段(如果未请求)的GenericResource
或GenericResourceCollection
。
它可以帮助防止应用因前端通过ajax动态请求的小型简单数据部分而过载路由和控制器函数。
GenericController
有五个路由
Method: POST /generic/list Method: POST /generic/create Method: POST /generic/update Method: POST /generic/item Method: POST /generic/delete
/generic/list get一个列表。它返回一个GenericResourceCollection
axios.post("/generic/list", { // table to query table: "users", // page to return page: 1, // item per page itemsPerPage: 10, // fileds to return fields: ["id", "name", "created_at", "role_id", "email", "company_id"], // where clause: rule is column: value or column: {operator: someoperator, value: somevalue} // operator value should be some of these: '=', '!=', '<', '<=', '>', '>=', '<>', 'like', 'contain' where: { // will generate ( created_at > '2021-03-11 20:26:00.0' ) created_at: { operator: ">", value: "2020-09-11 20:26:00.0" }, // will generate ( email_verified_at IS NOT NULL ) email_verified_at: { operator: "!=", value: null }, // when the operator's parameter is omitted the default operator will be '=', will generate ( role_id = 2 ) role_id: 2, // the non-existent 'contain' will generate ( email LIKE %legendary% AND email LIKE %zangetsu% ) // this example zangetsu.ins@company.com and jhon.legendary.dc@company.com will match email: { operator: "contain", value: ["legendary", "zangetsu"] }, }, //orWhere clause accept same rules as simple where with one more orWhere: { // you can pass an array as a value, it will generate (role_id = 1 OR role_id = 2) role_id: [1, 2], // will generate (role_id != 1 OR role_id != 2) role_id: { operator: "!=", value: [1, 2] }, }, whereIn: { // return items with those ids id: [1, 23, 35], }, whereNotIn: { // return items with neither of these ids id: [1, 23, 35], }, whereBetween: { // return items with price between 25 and 35 price: [25, 35], }, // return items with price less than 25 and greater than 35 whereNotBetween: { id: [25, 35], }, // order by id ascendingly of course the value can be DESC orderBy: { id: "ASC", }, });
注意:由于查询的通用性,无法在上述fields
参数中请求嵌套关系数据。使用DB外观进行查询,它返回stdClass类型。
/generic/create创建一个项。它将返回一个GenericResource
axios.post("/generic/create", { table: "roles", // fields to return in the GenericResource once created fields: ["id", "name"], // values: pair column: value values: { name: "Admin", slug: "admin", }, // can insert many in one request many: [ { name: "User editor", slug: "user-editor", }, { name: "Forum admin", slug: "forum-admin", }, ], });
/generic/update更新一个项。它将返回一个GenericResource
axios .post("/generic/update", { table: "roles", // id of the item to update id: 3, // many ids to update many items with the same values in one request. many: [35, 36, 37] // fields to return in the GenericResource once updated fields: ["id", "name"], // values: pair column: value values: { name: "Room Admin", slug: "room-admin", }, });
/generic/item获取一个项。它将返回一个GenericResource
axios.post("/generic/delete", { table: "user", // id of the item to delete id: 3, //fields to return in the GenericResource fields: ["id", "name", "slug"], });
/generic/delete删除一个项
axios .post("/generic/delete", { table: "user", // id of the item to delete id: 3, });
路由命名空间和分页配置
安装后,运行控制台命令 php artisan vendor:publish
将发布包的配置。也可以手动将/vendor/alcidesrh/generic-resource.php复制到/config
/config/generic-resource.php
return [ /* |-------------------------------------------------------------------------- | Laravel generic Resource package configuration |-------------------------------------------------------------------------- | */ // configure route and prefix // e.g. to have this route https://yourdomain/products/items for items list // change 'prefix' key value to 'products' and 'list_route_name' key value to 'items' 'route' => [ //Route's prefix for generic CRUD(create, read, update and delete) operations //Deafault 'generic' e.g.: axios.post( 'https://yourdomain/generic' ) 'prefix' => 'generic', //Route for list of generic items. //Deafault 'list' e.g. axios.post( 'https://yourdomain/generic/list' ) 'list_route_name' => 'list', //Route to create an item. //Deafault 'create' e.g. axios.post( 'https://yourdomain/generic/create', {table: 'users', values: [ {username: 'whatever', role_id: 1}], field: [id, username] } ) 'create_route_name' => 'create', //Route to update an item. //Deafault 'update' e.g. axios.post( 'https://yourdomain/generic/update', {table: 'users', id: 1, values: [ {username: 'whatever', role_id: 1}], field: [id, username] } ) 'update_route_name' => 'update', //Route to get an item. //Deafault 'item' e.g. axios.post( 'https://yourdomain/generic/item', {table: 'users', fields: [ {username: 'whatever', role_id: 1}] } ) 'show_route_name' => 'item', //Route to delete a generic item. //Deafault 'delete' e.g. axios.post( 'https://yourdomain/generic/delete', {table: 'users', id: 1} ) 'delete_route_name' => 'delete', ], // configure pagination items per page and parameters names. 'pagination' => [ //Items per page. Default 20. 'itemsPerPage' => 20, //Name of the param of the current page e.g. axios.post( 'https://yourdomain/generic/delete', {table: 'users', page: 1} ) 'name_param_page' => 'page', //Name of the param of the number of items per page e.g. axios.post( 'https://yourdomain/generic/list', {table: 'users', page: 1, itemsPerPage: 30} ) 'name_param_item_per_page' => 'itemsPerPage', ], ];
如果您认为这个包很有用,请考虑给它加星标。谢谢。
许可
此Laravel通用资源包是开源软件,受MIT许可许可。