lujo / laravel-rest
Laravel包,用于创建简单的REST API
2.0.0
2023-09-14 10:30 UTC
Requires
- php: >=8.0
- laravel/framework: >=v10.0.0
Requires (Dev)
- phpunit/phpunit: ^10.4-dev
README
Laravel包,用于创建简单的REST API。
安装
使用以下命令通过Composer安装此包:
composer require lujo/laravel-rest
或者你可以在composer.json中添加以下行
"require": { ... "lujo/laravel-rest": "*" }
然后运行
composer install
描述
此Laravel包包含两个类:RestRoute和RestController。
RestRoute在route(...)函数中执行特定资源的所有路由操作。RestController应该由其他控制器类扩展以用于特定资源。
用法
1. 创建Eloquent模型
为了使用此REST包,首先你必须为某些资源创建Eloquent模型。
示例:Article模型
<?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\Laravel\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. 创建路由
完成前两个步骤后,打开你的Laravel路由文件routes/web.php,并使用RestRoute类的静态函数route($router, $prefix, $controller, $include = null)创建路由结构。
示例routes/web.php路由
<?php use Laravel\Laravel\Routing\Router; use Lujo\Laravel\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=resource_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