direktori cari
阅读前篇 简介 Yii 是什么 从 Yii 1.1 升级 入门 安装 Yii 运行应用 第一次问候 使用Forms 数据库应用 使用 Gii 生成代码 进阶 应用结构 概述 入口脚本 应用(Applications) 应用组件(Application Components) 控制器(Controllers) 模型(Models) 视图(views) 模块(Modules) 过滤器(Filters) 小部件(Widgets) 前端资源(Assets) 扩展(Extensions) 请求处理 运行概述 启动引导(Bootstrapping) 路由和创建URL 请求(Requests) 响应(Responses) Sessions 和 Cookies 错误处理(Handling Errors) 日志(Logging) 关键概念 组件(Component) 属性(Property) 事件(Events) 行为(Behaviors) 配置(Configurations) 别名(Aliases) 类自动加载(Autoloading) 服务定位器(Service Locator) 依赖注入容器(Dependency Injection Container) 配合数据库工作 数据库访问 (Data Access Objects) 查询生成器(Query Builder) 活动记录(Active Record) 数据库迁移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用户数据 创建表单(Creating Forms) 输入验证(Validating Input) 文件上传(Uploading Files) 收集列表输入(Collecting Tabular Input) 多模型的复合表单(Getting Data for Multiple Models) 显示数据 格式化输出数据(Data Formatting) 分页(Pagination) 排序(Sorting) 数据提供器(Data Providers) 数据小部件(Data Widgets) 客户端脚本使用(Working with Client Scripts) 主题(Theming) 安全 认证(Authentication) 授权(Authorization) 处理密码(Working with Passwords) 客户端认证(Auth Clients) 最佳安全实践(Best Practices) 缓存 概述 数据缓存 片段缓存 页面缓存 HTTP 缓存 RESTfull Web服务 快速入门(Quick Start) 资源(Resources) 控制器(Controllers) 路由(Routing) 格式化响应(Response Formatting) 授权认证(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 错误处理(Error Handling) 开发工具 调试工具栏和调试器 使用Gii生成代码 生成API文档 测试 概述(Overview) 配置测试环境(Testing environment setup) 单元测试(Unit Tests) 功能测试(Function Tests) 验收测试(Acceptance Tests) 测试夹具(Fixtures) 高级专题 高级应用模板 创建自定义应用程序结构 控制台命令 核心验证器(Core Validators) 国际化 收发邮件 性能优化 共享主机环境 模板引擎 集成第三方代码 小部件 Bootstrap 小部件 Jquery UI 助手类 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
watak

资源

资源

RESTful 的 API 都是关于访问和操作 资源,可将资源看成MVC模式中的 模型

在如何代表一个资源没有固定的限定,在Yii中通常使用 yii\base\Model 或它的子类(如 yii\db\ActiveRecord) 代表资源,是为以下原因:

  • yii\base\Model 实现了 yii\base\Arrayable 接口,它允许你通过RESTful API自定义你想要公开的资源数据。
  • yii\base\Model 支持 输入验证, 在你的RESTful API需要支持数据输入时非常有用。
  • yii\db\ActiveRecord 提供了强大的数据库访问和操作方面的支持,如资源数据需要存到数据库它提供了完美的支持。

本节主要描述资源类如何从 yii\base\Model (或它的子类) 继承并指定哪些数据可通过RESTful API返回,如果资源类没有 继承 yii\base\Model 会将它所有的公开成员变量返回。

字段

当RESTful API响应中包含一个资源时,该资源需要序列化成一个字符串。 Yii将这个过程分成两步,首先,资源会被yii\rest\Serializer转换成数组, 然后,该数组会通过yii\web\ResponseFormatterInterface根据请求格式(如JSON, XML)被序列化成字符串。 当开发一个资源类时应重点关注第一步。

通过覆盖 yii\base\Model::fields() 和/或 yii\base\Model::extraFields() 方法, 可指定资源中称为 字段 的数据放入展现数组中,两个方法的差别为前者指定默认包含到展现数组的字段集合, 后者指定由于终端用户的请求包含 expand 参数哪些额外的字段应被包含到展现数组,例如,

// 返回fields()方法中申明的所有字段http://localhost/users

// 只返回fields()方法中申明的id和email字段http://localhost/users?fields=id,email

// 返回fields()方法申明的所有字段,以及extraFields()方法中的profile字段http://localhost/users?expand=profile

// 返回回fields()和extraFields()方法中提供的id, email 和 profile字段http://localhost/users?fields=id,email&expand=profile

覆盖 fields() 方法

yii\base\Model::fields() 默认返回模型的所有属性作为字段, yii\db\ActiveRecord::fields() 只返回和数据表关联的属性作为字段。

可覆盖 fields() 方法来增加、删除、重命名、重定义字段,fields() 的返回值应为数组,数组的键为字段名 数组的值为对应的字段定义,可为属性名或返回对应的字段值的匿名函数,特殊情况下,如果字段名和属性名相同, 可省略数组的键,例如

// 明确列出每个字段,适用于你希望数据表或模型属性修改时不导致你的字段修改(保持后端API兼容性)public function fields(){
    return [
        // 字段名和属性名相同
        'id',
        // 字段名为"email", 对应的属性名为"email_address"
        'email' => 'email_address',
        // 字段名为"name", 值由一个PHP回调函数定义
        'name' => function ($model) {
            return $model->first_name . ' ' . $model->last_name;
        },
    ];
}

// 过滤掉一些字段,适用于你希望继承父类实现同时你想屏蔽掉一些敏感字段public function fields(){
    $fields = parent::fields();

    // 删除一些包含敏感信息的字段
    unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);

    return $fields;
}

警告: 模型的所有属性默认会被包含到API结果中,应检查数据确保没包含敏感数据,如果有敏感数据, 应覆盖fields()过滤掉,在上述例子中,我们选择过滤掉 auth_keypassword_hash 和 password_reset_token.

覆盖 extraFields() 方法

yii\base\Model::extraFields() 默认返回空值,yii\db\ActiveRecord::extraFields() 返回和数据表关联的属性。

extraFields() 返回的数据格式和 fields() 相同,一般extraFields() 主要用于指定哪些值为对象的字段, 例如,给定以下字段申明

public function fields(){
    return ['id', 'email'];
}

public function extraFields(){
    return ['profile'];
}

http://localhost/users?fields=id,email&expand=profile 的请求可能返回如下JSON 数据:

[
    {
        "id": 100,
        "email": "100@example.com",
        "profile": {
            "id": 100,
            "age": 30,
        }
    },
    ...
]

链接

HATEOAS, 是Hypermedia as the Engine of Application State的缩写, 提升RESTful API 应返回允许终端用户访问的资源操作的信息,HATEOAS 的目的是在API中返回包含相关链接信息的资源数据。

资源类通过实现yii\web\Linkable 接口来支持HATEOAS,该接口包含方法 yii\web\Linkable::getLinks() 来返回 yii\web\Link 列表,典型情况下应返回包含代表本资源对象URL的 self 链接,例如

use yii\db\ActiveRecord;
use yii\web\Link;
use yii\web\Linkable;
use yii\helpers\Url;

class User extends ActiveRecord implements Linkable{
    public function getLinks()
    {
        return [
            Link::REL_SELF => Url::to(['user/view', 'id' => $this->id], true),
        ];
    }
}

当响应中返回一个User 对象,它会包含一个 _links 单元表示和用户相关的链接,例如

{
    "id": 100,
    "email": "user@example.com",
    // ...
    "_links" => {
        "self": {
            "target="_blank" href": "https://example.com/users/100"
        }
    }
}

集合

资源对象可以组成 集合,每个集合包含一组相同类型的资源对象。

集合可被展现成数组,更多情况下展现成 data providers. 因为data providers支持资源的排序和分页,这个特性在 RESTful API 返回集合时也用到,例如This is because data providers support sorting and pagination 如下操作返回post资源的data provider:

namespace app\controllers;

use yii\rest\Controller;
use yii\data\ActiveDataProvider;
use app\models\Post;

class PostController extends Controller{
    public function actionIndex()
    {
        return new ActiveDataProvider([
            'query' => Post::find(),
        ]);
    }
}

当在RESTful API响应中发送data provider 时, yii\rest\Serializer 会取出资源的当前页并组装成资源对象数组, yii\rest\Serializer 也通过如下HTTP头包含页码信息:

  • X-Pagination-Total-Count: 资源所有数量;
  • X-Pagination-Page-Count: 页数;
  • X-Pagination-Current-Page: 当前页(从1开始);
  • X-Pagination-Per-Page: 每页资源数量;
  • Link: 允许客户端一页一页遍历资源的导航链接集合.
可在快速入门 一节中找到样例.
Artikel sebelumnya: Artikel seterusnya: