flame/tiny-rest

Nette 框架的 REST 智能实现

v1.1.1 2016-12-30 14:28 UTC

README

Nette 框架 REST API 的智能且小巧实现

内容

  1. 需求
  2. 安装
  3. 配置
  4. 身份验证
  5. 路由和演示者
  6. 示例
  7. 赞助商

需求

完整的需求列表请参阅 此文件

安装

安装 flame\tiny-rest 的最佳方式是使用 Composer

$ composer require flame/tiny-rest:@dev

并注册扩展

extensions:
    rest: Flame\Rest\DI\RestExtension

配置

此软件包提供以下选项

  • authenticators - 实现了 Flame\Rest\Security\IAuthenticator 接口的类列表,用于身份验证请求。
  • cors - 跨域请求的设置列表
    • origin - 允许的来源列表,或 * 代表所有
    • headers - 允许的头部列表,或 * 代表所有
    • methods - 允许的方法列表,或 * 代表所有
  • ips - 允许的 IP 地址列表,或无内容代表允许所有
  • referers - 允许的引用者列表,或无内容代表允许所有

示例配置

tinyRest:
    cors:
        origin: *
        headers: *
        methods: *
    authenticators:
        - My\Super\Authenticator

身份验证

此软件包提供几种授权方法。

  1. 通过 IP 地址进行授权 - 当你在配置文件中设置 ips 选项时,此授权将自动启用。
  2. 通过 HTTP 引用者进行授权 - 当你在配置文件中设置 referers 选项时,此授权将自动启用。
  3. 通过跨域请求设置进行身份验证 - 当你在配置文件中设置 cors 选项时,此授权将自动启用,并遵循 这些 规则

下一个授权方法是基于令牌的授权。对于此授权类型,您必须执行以下步骤

  1. 您可以创建自己的身份验证器,实现 Flame\Rest\Security\IAuthenticator或者您可以使用此软件包中的默认身份验证器
  2. 您必须创建自己的令牌提供者类,实现 Flame\Rest\Security\Tokens\ITokenProvider。此类必须使用 getToken() 从请求中获取令牌(请求作为参数提供)并创建并返回一个新实例的 Flame\Rest\Security\Tokens\IToken(在那里您必须创建自己的实现或者您可以使用默认的)
  3. 您必须创建自己的 Flame\Rest\Security\Tokens\ITokenManager 实现,它提供验证令牌和获取特定令牌的标识的方法。

您可以在 示例 中查看实现。

路由和演示者

路由

此软件包提供一个基本路由

$router = new RouteList();
$router[] = new RestRoute('Api:V1');

return $router;

此路由有一个可选参数,用于指定模块路径以搜索演示者。在此示例中,预期模型名称为 Api 和 V1。

此路由器创建的 URL 结构为 /<module>/<presenter>[/<specific_action>][/<id>]。对于我们的示例,将是 /api/v1/<presenter>[/<specific_action>][/<id>]

所有这些 URL 都通过规则 action<create|update|read|readAll|delete><specific_action>(<id>) 映射到演示者中的操作,其中 POST = createPUT = updateDELETE = deleteGET(无 id)= readAllGET(有 id)= read。例如

  • GET /api/v1/accounts -> actionReadAll()
  • GET /api/v1/accounts/1 -> actionRead($id)
  • GET /api/v1/accounts/disabled/1 -> actionReadDisabled($id)

演示者

所有API演示者应扩展自RestPresenter。当您可以发送数据时,必须将其写入resource

public function actionRead($id) {
    $this->resource->id = $id;
    $this->resource->name = 'John';
}

或者为了更好的工作,您可以使用resourcedata属性

public function actionRead($id) {
    $this->resource->data = [
        'id' => $id,
        'name' => 'John'
    ];
}

在操作方法末尾自动发送响应,HTTP代码为200。当您可以更改它时,必须手动调用sendResource($code)

public function actionRead($id) {
    $this->resource->data = [
        'id' => $id,
        'name' => 'John'
    ];
    $this->sendResource(500);
}

并且对于处理和记录错误,您可以使用sendErrorResponse方法。

您可以从POST中获取数据,或通过inputgetInput()成员进行查询。您可以通过getQuery()获取查询值,通过getData()获取POST值,或通过getFiles()获取FILES

public function actionReadAll() {
    $limit = $this->getInput()->getQuery('limit');
    $this->resource->data = [
        'id' => $,
        'name' => 'John'
    ];
    $this->sendResource(500);
}

示例

路由器

$router = new RouteList();
$router[] = new RestRoute('Api:V1');

return $router;

演示者 AccountsPresenter.php

class AccountsPresenter extends RestPresenter
{
    /** User @inject */
    public $user;

    /**
     * @User loggedIn
     */
    public function actionReadAll()
    {
        $this->resource->data = $user->getIdentity();
    }
}

创建自己的Token实现

class Token implements IToken 
{
    private $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public function getToken()
    {
        return this->token;
    }
}

创建自己的TokenGetter

class TokenGetter implements ITokenGetter
{
    public function getToken(Request $request)
    {
        return new Token($request->getHeader('Authorozation'));
    }
}

创建自己的TokenManager

class TokenManager implements ITokenManager
{
    private $sessionManager;

    public function __construct(SessionManager $sessionManager) 
    {
        $this->sessionManager = $sessionManager;
    }

    public function isTokenValid(IToken $token)
    {
        $item = $this->sessionManager->getSessionByToken($token->getToken());

        return $item['expiration'] < new \DateTime();
    }

    public function getIdentity(IToken $token)
    {
        $item = $this->sessionManager->getSessionByToken($token->getToken());

        return $item['identity'];
    }
}

在这个例子中,当我在/api/v1/accounts上发送带有Authorization: valid头部的GET请求,并使用BasicAuthenticator通过@User注解进行身份验证时,API返回已登录用户的身份。

##赞助商 非常感谢这些朋友!

  • Ondra Zaruba(又名 @budry