tomhart / laravel-restful-controller


README

Build Status codecov Scrutinizer Code Quality GitHub release (latest by date) License: GPL v3

此库添加了一个 AbstractRestfulController 以简化 CRUD 控制器的繁重工作。

安装

您可以通过以下命令使用 composer 安装此包

composer require tomhart/laravel-restful-controller

用法

  • 创建一个继承自该类的控制器,并实现 getModelClass 方法
use TomHart\Restful\AbstractRestfulController;

class BlogController extends AbstractRestfulController 
{
    /**
     * What Model class to search for entities.
     * @return string
     */
    protected function getModelClass(): string
    {
        return Blog::class;
    }
}
  • 如果想让它渲染索引、显示或存储视图,添加一个 $views 属性
    /**
     * The views to render.
     * @var array
     */
    protected $views = [
        'index' => 'blog/index',
        'show' => 'blog/show',
        'store' => 'blog/store'
    ];

如果 $views 为空,指定的视图不存在,或者 Accept 标头为 application/json,则返回 JSON

  • 定义资源路由
Route::resource('blogs', 'BlogController');

注意,这也会定义一个 blogs.show.extrablogs.show.options 路由,稍后将进行解释。

/blogs/1 的示例响应

{
    "id": 1,
    "title":  "My Blog Post",
    "content":  "<h1>Title</h1><p>Some Content</p>"
}

关系

加载关系

显示路由可以返回您的模型关系。如果您发送一个包含要加载的逗号分隔值列表的 X-Load-Relationship 标头,请参阅 testRelationshipsCanBeReturned 测试以获取示例。

/blogs/1 的示例响应,带有 X-Load-Relationship: comments

{
    "id": 1,
    "title":  "My Blog Post",
    "content":  "<h1>Title</h1><p>Some Content</p>",
    "comments": [
        {
            "id": 1,
            "comment": "Great post!"        
        },
        { 
            "id": 2,
            "comment": "I enjoyed reading this"
        }
    ]  
}

访问关系

您可以使用上面提到的 .show.extra 路由来深入了解关系。如果第一个 comment 有一个作者,您想通过博客资源查看,您可以调用 /blogs/1/comments[0]/author

{
    "id": 1,
    "name": "Joe Bloggs"
}

您可以使用以下方式动态构建路由

route('blogs.show.extra', [
    'blog' => 1,
    'extra' => 'comments[0]/author'
]); 

限制对模型的访问

您可能想要限制对某些模型的访问,例如只加载当前登录用户的帖子。为此,您可以通过覆盖一些方法来实现。

索引页面

为了限制索引路由返回的模型,例如许多模型的分页列表,覆盖 createModelQueryBuilder 方法。

显示、更新和删除页面

为了限制可以显示、更新或删除的模型,覆盖 findModel 方法。

在保存或更新之前操作模型

如果您想在它们保存或更新之前操作模型,例如将 user_id 设置为当前登录用户,覆盖 saveModel 方法。

分页

默认情况下,如果可能,index 路由及其尝试加载的任何关系都将分页。

/blogs 的示例响应

{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            "id": 1
        },
        {
            "id": 2
        }
   ]
}

过滤

您可以通过查询字符串过滤 index 路由,例如 ?name=test

HasLinks

此库还提供了 HasLinks 接口和 HasLinksTrait 以提供默认实现。如果您将这些应用于您的模型,则响应将包含一个 _links 键,以帮助您的消费者导航并使用您的 API。

/blogs/1 的示例 _links

{  
    "id": 1,
    "title": "My Blog",
    "content": "See some _links!",
    "_links": {
        "index": {
            "method":  "get",
            "href": {
                "relative": "/blogs/",
                "absolute": "https://api.example.com/blogs/"
            }
        },
        "create": {
            "method":  "get",
            "href": {
                "relative": "/blogs/",
                "absolute": "https://api.example.com/blogs/"
            }
        },
        "store": {
            "method":  "post",
            "href": {
                "relative": "/blogs/",
                "absolute": "https://api.example.com/blogs/"
            }
        },
        "show": {
            "method":  "get",
            "href": {
                "relative": "/blogs/1",
                "absolute": "https://api.example.com/blogs/1"
            }
        },
        "update": {
            "method":  "put",
            "href": {
                "relative": "/blogs/1",
                "absolute": "https://api.example.com/blogs/1"
            }
        },
        "destroy": {
            "method":  "delete",
            "href": {
                "relative": "/blogs/1",
                "absolute": "https://api.example.com/blogs/1"
            }
        }
    }
}

前面提到的 .options 路由将简单地返回资源 indexcreatestore_links,因此您可以查询端点并获取与 API 交互所需的 URL。

如果您发送 {"id": X},它还会构建带有提供的 ID 的 showupdatedelete 路由。

构建器

此库还包括一个 Builder 类,用于从消费者视图与 API 交互。它支持标准的 getinsertupdatedelete 方法。

示例

use TomHart\Restful\Builder;

$models = Builder::model(MyModel::class)->where('name', 'test')->get(); // Collection

$modelWasInserted = Builder::model(MyModel::class)->insert(['name' => 'test']); //bool

$modelWasUpdated = Builder::model(MyModel::class)->update(1, ['name' => 'test']); //bool

$modelWasDeleted = Builder::model(MyModel::class)->delete(1); //bool

要使用它与您的模型一起使用,只需添加 implements Restful 并使用 InteractsWithRest 特性即可。