使用 Dingo API 扩展包快速构建 Laravel RESTful API(六) —— 转化器及响应构建器的高级使用

栏目: PHP · 发布时间: 5年前

内容简介:除了我们上篇教程介绍的一些基本使用之外,还可以通过传递额外的参数实现一些更高级的转化器功能。我们可以在响应构建器的但是这个功能只有在 Fractal 的序列化器为

转化器的高级功能

除了我们上篇教程介绍的一些基本使用之外,还可以通过传递额外的参数实现一些更高级的转化器功能。

资源键

我们可以在响应构建器的 itemcollectionpaginator 方法传入一个参数数组作为第三个参数,在这个数组中,可以通过 key 传入 Fractal 资源的类型标识:

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

但是这个功能只有在 Fractal 的序列化器为 JsonApiSerializer 时才有效。关于 Fractal 系列化器的设置我们下面会提到。

使用回调

Fractal 转化层允许你注册一个创建资源之后触发的回调,这个回调接收 League\Fractal\Resource\Item 或者 League\Fractal\Resource\Collection 资源作为第一个参数, League\Fractal\Manager 实例作为第二个参数,在这个回调函数中我们可以自定义序列化器、设置游标、以及其它与 Fractal 交互的功能。

设置序列化器

比如我们设置序列化器可以这么做(默认使用的序列化器是 DataArraySerializer ):

// 引入命名空间
use League\Fractal\Serializer\JsonApiSerializer;

$task = Task::findOrFail($id);
return $this->response->item($task, new TaskTransformer(), ['key' => 'task'], function ($resource, $fractal) {
        $fractal->setSerializer(new JsonApiSerializer());
    });

这样,我们访问对应的资源路由,返回的响应就变成了遵循 JSON-API 规范的数据格式:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(六) —— 转化器及响应构建器的高级使用

同时也会应用第三个参数设置的资源键值作为返回资源的数据类型。关于 Fractal 支持的其它序列化器可以参考之前的Fractal 教程。

设置游标

此外,学院君前面介绍 Fractal 对分页数据进行处理的时候讲到,对于结果集很大的、对性能要求严苛的系统,除了分页器之外,还可以通过游标获取分页数据,同样,也可以在第四个回调函数中设置游标来转化分页数据,下面我们改写 Api\TaskControllerindex 方法实现代码如下:

public function index(Request $request)
{
    $current = $request->input('current');
    $previous = $request->input('previous');
    $limit = $request->input('limit') ? : 10;

    if ($current) {
        $tasks = Task::where('id', '>', $current)->take($limit)->get();
    } else {
        $tasks = Task::take($limit)->get();
    }

    $next = $tasks->last()->id;
    $cursor = new Cursor($current, $previous, $next, $tasks->count());

    return $this->response->collection($tasks, new TaskTransformer, [], function ($resource, $fractal) use ($cursor) {
        $resource->setCursor($cursor);
    });
}

再次访问首页路由,就可以看到通过游标转化的分页数据了:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(六) —— 转化器及响应构建器的高级使用

自定义转化层

Dingo API 默认基于 Fractal 转化层实现转化器,你可以在 config/api.php 中看到这个默认配置:

'transformer' => env('API_TRANSFORMER', Dingo\Api\Transformer\Adapter\Fractal::class),

如果你不想使用 Fractal 作为转化层,可以在 Dingo API 中创建自己的转化层。要实现自定义的转化层,需要创建一个继承自 Dingo\Api\Contract\Transformer\Adapter 基类的子类,并且实现 transform 方法:

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

class MyCustomTransformerAdapter implements Adapter
{
    public function transform($response, $transformer, Binding $binding, Request $request)
    {
        // 调用转化层对响应数据进行转化
    }
}

transform 是唯一必须实现的方法(因为基类中只声明了这个抽象方法),你也可以添加自己需要的其他方法,就像 Dingo\Api\Transformer\Adapter\Fractal 那样。 transform 方法的目的是获取 $response ,然后和 $transformer 一起传递给转化层处理,转化层处理之后会返回一个数组,最终这个数组被 transform 方法返回。如果你的转化层很简单,可以完全在这个方法中实现所有逻辑。

$bindings 参数用于支持更多特性,比如添加元数据或者允许开发者通过回调与转化层交互。

$request 参数是当前的 HTTP 请求,当你的转化层需要查询字符串参数或者其他相关数据时会用到它。

自定义转化层类定义好了之后,可以将其配置到 .envAPI_TRANSFORMER 配置项作为全局默认转化层,也可以在运行时通过如下方式动态设置:

$this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
     return new MyCustomTransformerAdapter(...);
});

自定义响应数据格式

默认情况下,Dingo API 返回的响应会自动使用 JSON 格式并设置相应的 Content-Type 头。除了 JSON 之外 Dingo 还支持 JSONP 格式,该格式会将响应封装到一个回调中,要将响应数据默认格式调整为该格式,只需要简单将配置文件 config/api.php 中的默认 JSON 格式替换成 JSONP 即可:

'defaultFormat' => env('API_DEFAULT_FORMAT', 'json'),

'formats' => [
    'json' => Dingo\Api\Http\Response\Format\Jsonp::class,
],

默认情况下回调参数默认查询字符串是 callback ,这可以通过修改 Jsonp 构造函数的第一个参数来设置:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(六) —— 转化器及响应构建器的高级使用

如果查询字符串不包含任何参数将会返回 JSON 响应。当然,你还可以在运行时动态设置返回数据格式:

use Dingo\Api\Http\Response;

public function show($id)
{
    $task = Task::findOrFail($id);
    Response::addFormatter('json', new Response\Format\Jsonp);
    return $this->response->item($task, new TaskTransformer());
}

如果 Dingo 自带的 JSON 和 JSONP 格式满足不了你的需求,还可以自定义数据格式类。自定义的数据格式类需要继承自 Dingo\Api\Http\Response\Format\Format 基类,同时还要实现 formatEloquentModelformatEloquentCollectionformatArray 以及 getContentType 方法。

Morphing 和 Morphed 事件

在 Dingo API 发送响应之前会先对该响应数据进行转化(morph),这个过程包括运行所有转换器(Transformer)以及通过配置的响应数据格式发送响应。如果你需要控制响应数据如何被转化可以使用 Dingo 提供的 ResponseIsMorphing (转化前触发)和 ResponseWasMorphed (转化后触发)事件。

我们可以在 app/Listeners 目录下为上述事件创建监听器:

php artisan make:listener AddPaginationLinksToResponse

编辑 app/Listeners/AddPaginationLinksToResponse.php 代码如下:

<?php

namespace App\Listeners;

use Dingo\Api\Event\ResponseWasMorphed;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class AddPaginationLinksToResponse
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  object  $event
     * @return void
     */
    public function handle(ResponseWasMorphed $event)
    {
        if (isset($event->content['meta']['pagination'])) {
            $links = $event->content['meta']['pagination']['links'];
            $next = isset($links['next']) ? $links['next'] : null;
            $previous = isset($links['previous']) ? $links['previous'] : null;
            $event->response->headers->set(
                'link',
                sprintf('<%s>; rel="next", <%s>; rel="prev"', $next, $previous)
            );
        }
    }
}

然后通过在 EventServiceProvider 中注册事件及其对应监听器之间的映射关系来监听该事件:

use App\Listeners\AddPaginationLinksToResponse;
use Dingo\Api\Event\ResponseWasMorphed;

protected $listen = [
    ...
    ResponseWasMorphed::class => [
        AddPaginationLinksToResponse::class
    ]
];

现在所有包含分页链接的响应也会将这些链接添加到 Link 响应头。修改 Api\TaskControllerindex 方法实现代码如下:

public function index(Request $request)
{
    $limit = $request->input('limit') ? : 10;
    $tasks = Task::paginate($limit);
    return $this->response->paginator($tasks, new TaskTransformer());
}

在 Postman 中访问该方法对应路由,就可以看到相应结果:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(六) —— 转化器及响应构建器的高级使用


以上所述就是小编给大家介绍的《使用 Dingo API 扩展包快速构建 Laravel RESTful API(六) —— 转化器及响应构建器的高级使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

决战618:探秘京东技术取胜之道

决战618:探秘京东技术取胜之道

京东集团618作战指挥中心 / 电子工业出版社 / 2017-11 / 99

《决战618:探秘京东技术取胜之道》以京东技术团队备战618为主线,集合京东数百位技术专家,对京东所有和618相关的关键技术系统进行了一次全面的梳理和总结,是京东技术体系的智慧结晶。 《决战618:探秘京东技术取胜之道》从前端的网站、移动入口到后端的结算、履约、物流、供应链等体系,系统展示了京东最新的技术成就。同时,也涵盖了京东正在充分运用大数据、人工智能等先进技术对所有技术体系架构进行整体......一起来看看 《决战618:探秘京东技术取胜之道》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具