快速入门

未匹配的标注

快速入门

Yii 提供了一整套工具来简化实现 RESTful Web 服务 API 的任务。尤其是,Yii 支持以下关于 RESTful API 的特性:

  • 支持对 Active Record 的通用 API 的快速原型设计;
  • 响应格式的约定(默认支持 JSON 和 XML);
  • 对可选择输出的字段,提供可自定义的对象序列化支持;
  • 合理的格式化采集数据和验证错误;
  • 数据集合的分页、过滤与排序;
  • 支持 HATEOAS
  • 高效路由,并自带合理的 HTTP 动词检查;
  • 内置对 OPTIONS 和 HEAD 动词的支持;
  • 用户认证与授权;
  • 数据缓存和 HTTP 缓存;
  • 速率限制,即接口限流

下面,我们用一个例子来说明,如何用最少的代码工作量来构建一组 RESTful API。
假设,您希望通过 RESTful API 来展示用户数据。该用户数据存储在 user 数据库表中,并且您已经创建了活动记录类 app\models\User 来访问用户数据。

创建控制器

首先,创建一个控制器类 app\controllers\UserController,代码如下:

namespace app\controllers;

use yii\rest\ActiveController;

class UserController extends ActiveController
{
    public $modelClass = 'app\models\User';
}

控制器类继承自 yii\rest\ActiveController,它实现了一组公共的 RESTful 操作。通过指定 yii\rest\ActiveController::modelClassapp\models\User,控制器就知道哪个模型可以用来获取和操作数据。

配置 URL 规则

然后,在你的应用程序配置中修改 urlManager 组件的配置:

'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => 'user',
        ],
    ],
]

上面的配置主要为 user 控制器添加了一个 URL 规则,这样就可以使用美化的 URL 和有意义的 HTTP 动词访问和操作用户数据。

注意:Yii 将自动以复数形式将控制器名称用于端点(参考下面的 小试牛刀 章节),你可以使用yii\rest\UrlRule::$pluralize 属性来配置它。

支持 JSON 输入

要让 API 接受 JSON 格式的输入数据,需要配置 request 应用组件的 yii\web\Request::$parser 属性来使用这个针对 JSON 输入的 yii\web\JsonParser

'request' => [
    'parsers' => [
        'application/json' => 'yii\web\JsonParser',
    ]
]

注意:以上配置是可选的,如果没有上面的配置,API 将只能识别 application/x-www-form-urlencodedmultipart/form-data 输入格式。

小试牛刀

通过上述最简单的工作,您已经完成了创建用于访问用户数据的 RESTful API 的任务。您创建的 API 包括:

  • GET /users:逐页列出所有用户;
  • HEAD /users:显示用户列表的概览信息;
  • POST /users:创建一个新用户;
  • GET /users/123:返回用户 123 的详细信息;
  • HEAD /users/123:显示用户 123 的概览信息;
  • PATCH /users/123PUT /users/123:更新用户 123;
  • DELETE /users/123:删除用户 123;
  • OPTIONS /users:显示关于端点 /users 所支持的动词;
  • OPTIONS /users/123:显示关于端点 /users/123 所支持的动词。

你可以使用 curl 命令访问 API,具体如下:

$ curl -i -H "Accept:application/json" "http://localhost/users"

HTTP/1.1 200 OK
...
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
      <http://localhost/users?page=2>; rel=next,
      <http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

[
    {
        "id": 1,
        ...
    },
    {
        "id": 2,
        ...
    },
    ...
]

尝试将可接受的内容类型(content type)更改为 application/xml,您将看到结果以 XML 格式返回:

$ curl -i -H "Accept:application/xml" "http://localhost/users"

HTTP/1.1 200 OK
...
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self, 
      <http://localhost/users?page=2>; rel=next, 
      <http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <item>
        <id>1</id>
        ...
    </item>
    <item>
        <id>2</id>
        ...
    </item>
    ...
</response>

下面的命令将通过以 JSON 格式发送带有用户数据的 POST 请求来创建一个新用户:

$ curl -i -H "Accept:application/json" -H "Content-Type:application/json"
    -XPOST "http://localhost/users"
    -d '{"username": "example", "email": "user@example.com"}'

HTTP/1.1 201 Created
...
Location: http://localhost/users/1
Content-Length: 99
Content-Type: application/json; charset=UTF-8

{"id":1,"username":"example","email":"user@example.com","created_at":1414674789,"updated_at":1414674789}

Tip:您也可以通过输入URL http://localhost/users 通过Web浏览器访问api。然而,您可能需要一些浏览器插件来发送特定的请求头。

如您所见,在响应头中,有关于总计数、页面计数等信息,也有一些链接允许您导航到其他数据页面。例如,http://localhost/users?page=2 会给出用户数据的下一页。

使用 fieldsexpand 参数,您还可以指定结果中应该包含哪些字段。例如,URL http://localhost/users?fields=id,email 将只返回 idemail 字段。

Info:您可能已经注意到 http://localhost/users 的结果包含一些敏感字段,如 password_hashauth_key。您当然不希望这些出现在 API 结果中。您可以并且应该从结果中删除这些字段,如参考资源(Resources)章节所述。

此外,您还可以对数据集合进行排序,如 http://localhost/users?sort=emailhttp://localhost/users?sort=-email,也可以对数据集合进行过滤,如 http://localhost/users?filter[id]=10http://localhost/users?filter[email][like]=gmail.com 可以通过使用数据过滤器来实现。有关详细信息,请参阅资源(Resources)章节。

自定义列表分页和排序

为了改变默认的分页和排序模型列表,你可以在你的控制器中配置 yii\rest\IndexAction。例如:

namespace app\controllers;

use yii\rest\ActiveController;
use yii\helpers\ArrayHelper;

class UserController extends ActiveController
{
    public $modelClass = 'app\models\User';

    public function actions()
    {
        return ArrayHelper::merge(parent::actions(), [
            'index' => [
                'pagination' => [
                    'pageSize' => 10,
                ],
                'sort' => [
                    'defaultOrder' => [
                        'created_at' => SORT_DESC,
                    ],
                ],
            ],
        ]);
    }
}

请查看 扩展 ActiveController 来获取配置 ActiveController 的动作(actions)的详细信息。

小结

使用 Yii RESTful API 框架,可以根据控制器操作实现 API 端点(endpoint),并且可以使用控制器组织动作(action),这些动作为单一类型的资源实现端点。

资源(Resources)被表示为 yii\base\Model 类扩展的数据模型。如果您正在使用数据库(关系型或 NoSQL),建议您使用 yii\db\ActiveRecord 来表示资源。

你可以使用 yii\rest\UrlRule 来简化到你的 API 端点的路由。

虽然不是必需的,但建议您将 RESTful API 开发为独立的应用程序(如,命名为 api),与 Web 前端(frontend)和后端(backend)不同,以便更容易维护。

💖喜欢本文档的,欢迎点赞、收藏、留言或转发,谢谢支持!
作者邮箱:zhuzixian520@126.com,github地址:github.com/zhuzixian520

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
zhuzixian520
讨论数量: 0
发起讨论 只看当前版本


暂无话题~