indatus/ranger

此包通过允许您使用HTTP查询参数指定连接和预加载关联,为您的API REST服务器添加了一些功能。

0.7.0 2014-03-14 00:22 UTC

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安装

您可以通过将以下行添加到您的composer.json文件中的require块来通过Composer安装此库

"indatus/ranger": "dev-master"

接下来运行 composer install

返回顶部

## 在Laravel中配置

目前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/