lujo / lumen-rest
Lumen包,用于创建简单的REST API
2.0.0
2023-10-13 14:40 UTC
Requires
- php: >=8.0.0
- laravel/lumen-framework: ^10.0
Requires (Dev)
- orchestra/testbench: ^v8.13
- phpunit/phpunit: ^10.1
README
Lumen包,用于创建简单的REST API。
安装
使用以下命令通过composer安装此包:
composer require lujo/lumen-rest
或者在composer.json
中添加以下行:
"require": { ... "lujo/lumen-rest": "*" }
然后运行:
composer install
描述
此Lumen包由两个类组成:RestRoute
和RestController
。
RestRoute
在函数route(...)
中执行特定资源的所有路由操作。RestController
应该被扩展为其他控制类,用于特定资源。
使用方法
1. 创建Eloquent模型
为了使用此REST包,首先你必须为某些资源创建Eloquent模型。
例如:文章模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $table = 'article'; protected $fillable = [ 'title', 'description', 'content' ]; // Optional realtions and other Eloquent stuff public function articleAuthor() { return $this->hasOne('App\Models\Author'); } }
2. 创建控制器
创建模型后,你可以创建简单的控制器类,并从这个包中扩展RestController
类。你还必须实现函数getModel()
,该函数必须返回你在上一步中创建的Eloquent模型,这是你想通过此REST API公开的资源。
例如:控制器类
<?php namespace App\Http\Controllers; use Illuminate\Database\Eloquent\Model; use App\Models\Article; use Lujo\Lumen\Rest\RestController; class ArticleController extends RestController { /** * @return Model */ protected function getModel() { return new Article(); } // Optional override, transforms every model before returning it from API. protected function beforeGet($model) { return $model; } // Optional override, transform received request before creating new model from it. protected function beforeCreate($request) { return $request->all(); } // Optional override, transform received request before updating existing model from it. protected function beforeUpdate($request) { return $request->all(); } // Optional override, perform some action on/with model before it is deleted. protected function beforeDelete($model) { return null; } // Optional override, specify list of relations to return on specific action protected function getWith($request, $action) { if($action === 'INDEX') { return ['text']; } return ['author', 'comments', 'text']; } // Optional override, specify list of where statements to return on specific action protected function getWhere($request, $action) { if($action === 'DELETE') { return [['name', 'Test']]; } return [['status', 'ACTIVE'], ['enabled', true]]; } // Optional override, specify additional where query statement in form of a anonymous function protected function getWhereFunction($request, $action) { return function($q) { $q->where('name', 'Test')->orWhere('status', 'ACTIVE'); }; } // Optional override, when INDEX method is called and this method returns true, the returend JSON will contain // count data used for pagination e.g. {result_count: 10, total_count: 45, data: [...results]} protected function withCountMetadata($request) { return false; } }
如果你不使用它们,所有可选的覆盖函数都不需要,它们可以从你的控制器类实现中安全地省略。
3. 创建路由
完成前两个步骤后,打开你的Lumen路由文件routes/web.php
,并使用RestRoute
类的静态函数route($router, $prefix, $controller, $include = null)
创建路由结构。
例如:routes/web.php
路由
<?php use Laravel\Lumen\Routing\Router; use Lujo\Lumen\Rest\RestRoute; /** * @var $router Router */ // This will create all article routes ('INDEX', 'ONE', 'CREATE', 'UPDATE', 'DELETE') for routes /articles/* RestRoute::route($router, 'articles', 'ArticleController', 'middleware1'); // This will create only 'INDEX' and 'ONE' for routes /users/* RestRoute::route($router, 'users', 'UserController', ['middleware1', 'middleware2'], ['INDEX', 'ONE']); // This will create only 'INDEX', 'CREATE' and 'UPDATE' routes for /example/* but apply middlewares only on CREATE and UPDATE RestRoute::route($router, 'examples', 'ExampleController', ['CREATE' => ['middleware1', 'middleware2'], 'UPDATE' => 'middleware2'], ['INDEX', 'CREATE', 'UPDATE']); // This will create all routes and apply middleware1 and middleware2 to INDEX and ONE route, on others will middleware3 be applied. RestRoute::route($router, 'users', 'UserController', ['INDEX,ONE' => ['middleware1', 'middleware2'], 'middleware3']); // Example subgroup of routes (/article/authors/*) with middleware $router->group(['prefix' => 'article', 'middleware' => 'middleware1'], function ($subRoute) { RestRoute::route($subRoute, 'authors', 'AuthorController'); } );
生成的REST资源路由格式如下
** 获取所有资源 ** 具有以下HTTP GET URL参数
- skip - 跳过的资源数量(例如,30)
- limit - 要检索的资源数量(例如,15)
- sort - 要排序返回资源的字段(例如,'first_name')
- order - 返回资源的排序('asc'或'desc')
示例HTTP GET请求: http://site.com/api/resource?skip=30&limit=6&sort=name&order=desc
响应
头部
Content-type: application/json
X-Total-Count: 10
X-Result-Count: 6
当方法withCountMetadata()返回false时的主体
[
{"id": 31, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 32, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 33, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 34, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 35, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 36, "resource_name": "Resource name", "description": "Some resource description"}
]
当方法withCountMetadata()返回true时的主体
{
total_count: 10,
result_count: 6,
data: [
{"id": 31, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 32, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 33, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 34, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 35, "resource_name": "Resource name", "description": "Some resource description"},
{"id": 36, "resource_name": "Resource name", "description": "Some resource description"}
]
}
许可
MIT