2.6. Transformers

优质
小牛编辑
129浏览
2023-12-01

Transformers 允许你便捷地、始终如一地将对象转换为一个数组。通过使用一个 transformer 你可以对整数和布尔值,包括分页结果和嵌套关系进行类型转换。

专业术语

在这一章 "transformer" 这个词用得很多。需要注意下面的词语在使用的时候是什么意思,因为这些词贯穿了整个章节。

  • 转换层 是一个类库,它负责准备和操作 transformers 。
  • 一个 transformer 是一个类,它会获取原始数据并将返回一个格式化之后的标准数组。

使用 Transformers

这里有两种使用 transformers 的方法。

为一个类注册一个 Transformer

当你为一个指定的类注册一个 transformer 时,你将能够直接从你的路由中返回这个类(假设它可以变成一个数组),并且通过 transformer 自动运行。这对于那些简单的 API 来说非常有用,因为在你使用模型的地方,你可以轻而易举的从路由中返回这个模型。

app('Dingo\Api\Transformer\Factory')->register('User', 'UserTransformer');

使用响应生成器

返回 响应生成器 小节,查看如何使用。

Fractal

Fractal 是包使用的默认转换层。 它拥有许多有用的功能,可帮助您保持数据的一致性。

要使用 Fractal,建议你去它们的网站阅读文档。

自动关系预加载

当使用 Fractal 的引入功能嵌入关系的时候,你应该确保你在你的模型中定义了相同的名字。这个包会自动为你预加载这些关系,以减少查询数量。

更多配置

Fractal 被注册为默认的数据转换层,并使用默认的配置。定义嵌入的关系时,如果要自定义 include 关键词和分隔符,你必须在 service provider 或启动文件中手动实例化 Dingo\Api\Transformer\Adapter\Fractal 类。

$this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
     return new Dingo\Api\Transformer\Adapter\Fractal(new League\Fractal\Manager, 'include', ',');
});

如果你正在使用 Lumen 你可以在启动文件里面这样设置。

app('Dingo\Api\Transformer\Factory')->setAdapter(function ($app) {
    return new Dingo\Api\Transformer\Adapter\Fractal(new League\Fractal\Manager, 'include', ',');
});

响应生成器的高级用法

将Fractal与响应构建器一起使用通常是从控制器返回数据的最佳方法。

响应生成器上的 itemcollectionpaginator 方法都能接收一些额外的参数用于进一步自定义 Fractal 。

资源键

return $this->item($user, new UserTransformer, ['key' => 'user']);

使用回调

Fractal 转换层允许你在创建资源后注册一个可触发的回调方法。这个回调函数接收一个 League\Fractal\Resource\Item 或者 League\Fractal\Resource\Collection 实例作为第一个参数,接收 League\Fractal\Manager 实例作为第二个参数。然后你可以使用它与资源进行更复杂的交互。

最典型的用法就是你可以在设置游标用来进行数据分页或者更改基本响应数据序列化的方式。

return $this->collection($users, new UserTransformer, [], function ($resource, $fractal) {
    $resource->setCursor($cursor);
});

如果你不使用资源键参数,可以省略空数组,直接把回调方法作为第三个参数。

return $this->collection($users, new UserTransformer, function ($resource, $fractal) {
    $fractal->setSerializer(new CustomSerializer);
});

自定义转换层

在 dingo/api 里,你可以轻松地自定义 Transformer 的数据格式。只需要创建一个实现了 Dingo\Api\Contract\Transformer\Adapter 接口的类并且包含 transform 方法即可:

use Dingo\Api\Http\Request;
use Dingo\Api\Transformer\Binding;
use Dingo\Api\Contract\Transformer\Adapter;

class MyCustomTransformer implements Adapter
{
    public function transform($response, $transformer, Binding $binding, Request $request)
    {
        // 在这里可以使用你的转换层转换给出的响应
    }
}

transform 方法是唯一必需的,除此之外你可以随意添加其他方法。transform 方法的目的就是获取 $response ,然后把它和 $transformer 一起发到转换层。转换层这里应该由 transform 方法返回一个数组。当然,如果转换非常简单,可直接在类内部实现转换。

$binding 参数可以让转换层具有更高级的特性,比方,增加元数据或者允许其他开发者通过回调方法和你的转换层进行交互。

$request 参数是指当前正在进行的 HTTP 请求,当你需要请求中的相关数据,这个可以派上用场。

最后更新:

类似资料

  • 问题内容: 这段代码: 调用此方法: 给我一个ClassCastException->跟踪的一部分: 这很奇怪,因为,实际上,如果您查找Hibernate的源代码,它将尝试执行以下操作: 这没有任何意义… 目标的类型为Class,此代码尝试将其强制转换为Map, 为什么要尝试这样做??? 任何指针都值得欢迎… 我正在使用Hibernate 5(并且正在从3升级)… 编辑:我也使用Spring(4.

  • 问题内容: 我接下来还有几粒豆: 我正在尝试执行下一个Hibernate查询: 问题: 我了解Hibernate正在寻找类似的东西: 代替: 关于如何在不创建新bean的情况下解决此问题的想法? 谢谢! 问题答案: 我写了一个ResultTransformer可以解决您的问题。它的名称是AliasToBeanNestedResultTransformer,请在github上查看。

  • 问题内容: Query query = getHibernateTemplate().getSessionFactory().getCurrentSession().createSQLQuery( “select proj_employee.employee_no as employeeNo, … .setResultTransformer(Transformers.aliasToBean(Use

  • 问题内容: 我正在尝试通过加入实体类来创建BO 我得到100个空BO,即所有属性均为null我的BO如下 ..... 当我删除aliasToBean行并遍历Object []时,我可以看到已获取正确的值,请指导我… 问题答案: 尝试显式地对项目进行别名化,以匹配Bean中的字段名称,如下所示:

  • 注意,这一节的内容最早由 Pascal Voitot 发表在 mandubian.com 上。(文章太旧,请带着批判的眼光去读。) 现在已经知道如何验证 JSON,以及如何将 JSON 转成任意结构或将任意结构转成 JSON。但当我开始用那些组合子来写 web 应用,我立即遇到了这样的情况:从网络中读取 JSON,验证它然后再将它转成 JSON。 JSON coast-to-coast 设计介绍

  • Transformers 是一套基于 Javascript(JS) 的已彻底组件化与模块化的开发框架,与 Web Components 理念一致。框架主要关注组件路由、组件消息传递和组件异步加载等,其中要解决的核心问题是组件间的解耦。 快速开始 引入 jQuery <script src="http://javascript.u.qiniudn.com/jquery/1110.js"></scri