alcidesrh/laravel-generic-resource

通用的或不可知性的Laravel资源及其CRUD(创建、读取、更新、删除)操作。

v1.0.2 2021-04-05 04:21 UTC

This package is auto-updated.

Last update: 2024-09-22 09:43:58 UTC


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资源。


目录
  1. 要求
  2. 安装
  3. 使用

要求

-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文档的指南线,GenericResourceGenericResourceCollection类被制作出来,并添加了一些额外的代码以使其通用。因此,您可以期望具有相同的结构和行为。


GenericController

此包的主要目标是提供GenericResourceGenericResourceCollection。然而,此包还提供了一个GenericController,可以用于获取不需要复杂查询或转换的数据,并仅返回请求的字段或所有字段(如果未请求)的GenericResourceGenericResourceCollection

它可以帮助防止应用因前端通过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许可许可。