indatus / ranger
此包通过允许您使用HTTP查询参数指定连接和预加载关联,为您的API REST服务器添加了一些功能。
Requires
- php: >=5.4.0
- illuminate/container: 4.1.*@dev
- illuminate/database: 4.1.*@dev
- illuminate/routing: 4.1.*@dev
- illuminate/support: 4.1.*
- illuminate/view: 4.1.*@dev
Requires (Dev)
- mockery/mockery: dev-master@dev
- phpunit/phpunit: 3.7.*@dev
This package is not auto-updated.
Last update: 2024-09-14 15:27:16 UTC
README
API基础控制器是一个Laravel包,它允许您快速启动API。创建API的过程可能非常繁琐,尤其是当您考虑验证、错误和响应代码如何处理时。与其如此繁琐,不如安装ranger,扩展ApiBaseController(见下方的示例),就这样。如果您觉得需要更符合您需求的定制,Ranger遵循开/闭原则,因此扩展核心组件非常容易。
Ranger允许进行以下操作:
搜索
预加载
连接
左连接
Ranger还支持嵌套和非嵌套资源。它处理Json和HTML内容类型,但也可以轻松扩展以支持其他内容类型。
## README内容您可以通过将以下行添加到您的composer.json文件中的require块来通过Composer安装此库
"indatus/ranger": "dev-master"
接下来运行 composer install
目前Ranger仅与Laravel框架一起工作。然而,我们确实有计划使其成为无框架的包。
要发布此配置到 app/config/packages/indatus/ranger 文件夹,您需要运行以下操作
php artisan config:publish indatus/ranger
最后一步是添加服务提供者。打开 app/config/app.php
,并将新项目添加到providers数组中。
'Indatus\Ranger\RangerServiceProvider'
就这样。现在您可以使用Ranger了。请查看下方的示例。
## 配置选项Ranger设置(ranger.php)
Ranger附带一些配置选项。您可以为API中的结果设置内容类型。您还可以选择是否要分页结果或返回整个集合。如果需要分页,您可以设置per_page值。
注意: 此配置中的std_search选项是为未来版本准备的。自行承担更改风险,但建议您现在不要更改这些值。随着我们扩展搜索功能,这些值将在未来的版本中更具可配置性。
通过仅扩展ApiBaseController类即可实现所有这些功能。
假设您已经采取了适当的步骤设置Eloquent模型以及迁移。
本文档中的示例直接来自上面的示例应用程序,创建了两个实体:用户和账户。
示例
## Non-Nested Resource Example **Here's an example of a non-nested resource**<?php class UsersController extends Indatus\Ranger\ApiBaseController { /** * Illuminate\Database\Eloquent * * @var User */ protected $user; public function __construct(User $user) { $this->user = $user; } /** * @return Illuminate\View\Environment | Json string */ public function index() { return $this->handleAction($this->user); } /** * @return Illuminate\Routing\Redirector | Json string */ public function store() { return $this->handleAction($this->user); } /** * @param $id - id of the model instance * @return Illuminate\View\Environment | Json string */ public function show($id) { return $this->handleAction($this->user, $id); } /** * @param int $id * @return Illuminate\Routing\Redirector | Json string */ public function update($id) { return $this->handleAction($this->user, $id); } /** * * @param int $id * @return Illuminate\Routing\Redirector | Json string */ public function destroy($id) { return $this->handleAction($this->user, $id); } }
[Back To Top](#top)
**Next, let's have a look at the routes file in app/routes.php**
<?php //It's always a good idea to prefix your api Route::group(['prefix' => 'v1'], function() { Route::resource('users', 'UsersController'); });
**Throughout this readme, I will assume the url of your code will be http://www.example.com**
http://www.example.com/v1/users GET Request will return a collection of all users in json format ie):
{ "collection": [ { "id": "1", "name": "Charles Griffin", "email": "cgriffin@indatus.com", "created_at": "2014-03-04 02:25:03", "updated_at": "2014-03-04 02:25:03" }, { "id": "2", "name": "Test User", "email": "test_user@gmail.com", "created_at": "2014-03-04 02:25:03", "updated_at": "2014-03-04 02:25:03" } ], "response_code": 200 }
[Back To Top](#top)
http://www.example.com/v1/users/1 GET request will return a single user instance in json format ie):
{ "instance": { "id": "1", "name": "Charles Griffin", "email": "cgriffin@indatus.com", "created_at": "2014-03-04 02:25:03", "updated_at": "2014-03-04 02:25:03" }, "response_code": 200 }
[Back To Top](#top)
http://www.example.com/v1/users POST request will add a user to the database and return:
{ "instance": { "name": "Another User", "email": "user@example.com", "updated_at": "2014-03-04 02:56:59", "created_at": "2014-03-04 02:56:59", "id": 4 }, "response_code": 201 }
[Back To Top](#top)
http://www.example.com/v1/users/1 DELETE request will delete a single user instance and return the following:
{ "delete_message": ['successful deletion'], "response_code": 204 }
[Back To Top](#top)
http://www.example.com/v1/users/1 PUT request will update a single user instance and return the following:
{ "instance": { "id": "1", "name": "Charles Updated", "email": "charles_updated@indatus.com", "created_at": "2014-03-04 02:58:43", "updated_at": "2014-03-04 03:15:33" }, "response_code": 200 }
[Back To Top](#top)
http://www.example.com/v1/users?eagerLoads[0]=accounts GET request will return all users along with their accounts:
{ "collection": [ { "id": "1", "name": "Charles Griffin", "email": "cgriffin@indatus.com", "created_at": "2014-03-04 03:22:57", "updated_at": "2014-03-04 03:22:57", "accounts": [ { "id": "1", "user_id": "1", "name": "Us Bank", "current_balance": "1500.00", "created_at": "2014-03-04 03:22:57", "updated_at": "2014-03-04 03:22:57" } ] }, { "id": "2", "name": "Test User", "email": "test_user@gmail.com", "created_at": "2014-03-04 03:22:57", "updated_at": "2014-03-04 03:22:57", "accounts": [ { "id": "2", "user_id": "2", "name": "PNC Bank", "current_balance": "100.00", "created_at": "2014-03-04 03:22:57", "updated_at": "2014-03-04 03:22:57" } ] } ], "response_code": 200 }
[Back To Top](#top)
http://www.example.com/v1/users?joins[0]=accounts:users.id=accounts.user_id GET request will return all users along with their accounts joined:
{ "collection": [ { "id": "1", "name": "Us Bank", "email": "cgriffin@indatus.com", "created_at": "2014-03-04 03:22:57", "updated_at": "2014-03-04 03:22:57", "user_id": "1", "current_balance": "1500.00" }, { "id": "2", "name": "PNC Bank", "email": "test_user@gmail.com", "created_at": "2014-03-04 03:22:57", "updated_at": "2014-03-04 03:22:57", "user_id": "2", "current_balance": "100.00" } ], "response_code": 200 }
搜索:http://www.example.com/v1/users?searchParams[property]=name&searchParams[operator]=like&searchParams[value]=%Ch%
{
"collection": [
{
"id": "1",
"name": "Charles Griffin",
"email": "cgriffin@indatus.com",
"created_at": "2014-03-04 03:22:57",
"updated_at": "2014-03-04 03:22:57"
}
],
"response_code": 200
}
## Nested Resource Example **Here's an example of a nested resource controller**
<?php class AccountsController extends Indatus\Ranger\ApiBaseController { //because it's a nested resource we must have this protected $belongsTo = 'users'; /** * account Repository * * @var account */ protected $account; public function __construct(Account $account) { $this->account = $account; } /** * Display all accounts for a specific user. * * @param int $user_id The user id * @return View or JSON response based on the request */ public function index($user_id) { $passToView = ['test' => 'this is a test message']; return $this->handleAction($this->account, null, compact('user_id'), $passToView); } /** * Show the form for creating a new account. * * @param int $user_id The user id * @return View for creating a new account */ public function create($user_id) { return $this->handleAction($this->account, null, compact('user_id')); } /** * Store a newly created account. * * @param int $user_id The user id * @return Redirect or JSON response based on the request format */ public function store($user_id) { return $this->handleAction($this->account, null, compact('user_id')); } /** * Display the specified account. * * @param int $user_id The user id * @param int $id The account id * @return View or JSON response based on the request format */ public function show($user_id, $id) { return $this->handleAction($this->account, $id, compact('user_id')); } /** * Show the form for editing the specified account. * * @param int $user_id The user id * @param int $id The account id * @return View for updating a account */ public function edit($user_id, $id) { // if using html, you can pass additional parameters to the view $passToView = ['test' => 'this is a test message']; return $this->handleAction($this->account, $id, compact('user_id'), $passToView); } /** * Update the specified account. * * @param int $user_id The user id * @param int $id The account id * @return Redirect or JSON response based on the request format */ public function update($user_id, $id) { return $this->handleAction($this->account, $id, compact('user_id')); } /** * Remove the specified account from storage. * * @param int $user_id The user id * @param int $id The account id * @return Redirect or JSON response based on the request format */ public function destroy($user_id, $id) { return $this->handleAction($this->account, $id, compact('user_id')); } }
[Back To Top](#top)
**Next, let's have a look at the routes file in app/routes.php.** Nested resources are a little different
<?php //It's always a good idea to prefix your api Route::group(['prefix' => 'v1'], function() { Route::resource('users.accounts', 'AccountsController'); });
Now you will be able to access the data in the same manner as the non nested resource above. The only difference is the urls will be the following:
GET http://example.com/v1/users/1/accounts returns all accounts for the user with id of 1 GET http://example.com/v1/users/1/accounts/1 returns account with id of 1 for the user with id of one. If the user doesn't own that account, then ModelNotFoundException (404 error) is thrown GET (with eager loads) http://www.example.com/v1/users/1/accounts?eagerLoads[0]=transactions returns all accounts for the given user and eager loads that account's transactions GET (with joins) http://www.example.com/v1/users/1/accounts?joins[0]=transactions:accounts.id=transactions.account_id returns all accounts for the given user and join that account's transactions GET (with Left Joins) http://www.example.com/v1/users/1/accounts?leftJoins[0]=transactions:accounts.id=transactions.account_id returns all accounts for the given user and left join that account's transactions DELETE http://www.example.com/v1/users/1/accounts/1 Deletes the account if it belongs to the user, otherwise, 404 error gets returned PUT http://www.example.com/v1/users/1/accounts/1 updates the account if it belongs to the user otherwise 404 error gets returned POST http://www.example.com/v1/users/1/accounts Adds an account for the given user
## 安全性
安全性:默认情况下,我们不会提供进行这些操作的认证。认证应由开发人员实现,因为这非常具体于应用程序。我们认为,有必要就安全性发表声明,因为没有它,任何人都可以访问您的API上的数据。
请注意,此包消除了开发API时的许多痛点,而您将不得不在重新发明轮子的基础上编写自己的认证。
我们正在开发一个示例应用程序,将向您展示基本认证。
## 如何解决基本问题问题:
即使您确信您的HTTP请求正在工作,您仍然会收到InvalidInputException异常。
##解决方案
如果您正在尝试访问上述API端点之一(例如example.com/api/users)并收到InvalidInputException异常,这很可能是由于您的Apache或nginx配置设置不当。
如果您正在使用Apache,请确保您的 .htaccess 文件看起来如下所示
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
如果您正在使用Nginx,请参阅以下内容
http://phawk.co.uk/blog/laravel-4-nginx-config/