使用 Dingo API 扩展包快速构建 Laravel RESTful API(五) —— 转化器篇(下):结合响应构建器构...

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

内容简介:Dingo API 提供的转化器(Transformer)正是基于Fractal 对响应数据格式进行一致性的转化。在 Dingo 中定义的转化器类和 Fractal 中完全一致,Dingo 仅仅是在响应实现时对 Fractal 做了一层封装而已,所以我们可以完全基于上篇教程创建的转化器类进行本篇教程的演示。在 Dingo API 中使用转化器最简单的方式就是先注册模型类于转化器之间的映射关系,然后在定义 API 的路由中返回这个模型类实例,Dingo 底层会自动按照映射的转化器对模型对象数据进行转化并返回给

Dingo API 提供的转化器(Transformer)正是基于Fractal 对响应数据格式进行一致性的转化。

在 Dingo 中定义的转化器类和 Fractal 中完全一致,Dingo 仅仅是在响应实现时对 Fractal 做了一层封装而已,所以我们可以完全基于上篇教程创建的转化器类进行本篇教程的演示。

为模型类注册转化器

在 Dingo API 中使用转化器最简单的方式就是先注册模型类于转化器之间的映射关系,然后在定义 API 的路由中返回这个模型类实例,Dingo 底层会自动按照映射的转化器对模型对象数据进行转化并返回给客户端。

通常我们会在某个服务提供者(如 AppServiceProvider ) 的 boot 方法中注册模型类与转化器之间的映射:

<?php

namespace App\Providers;

use App\Task;
use App\Transformers\TaskTransformer;
use Dingo\Api\Transformer\Factory;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    ...

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        app(Factory::class)->register(Task::class, TaskTransformer::class);
    }
}

然后我们去修改之前创建的 Api\TaskControllershow 方法如下:

public function show($id)
{
    $task = Task::findOrFail($id);
    return $this->response->array($task);
}

再在 Postman 中访问这个路由,就可以获取到通过 TaskTransformer 转化的 Task 对象数据:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(五) —— 转化器篇(下):结合响应构建器构...

这种使用方式在直接返回模型实例的简单 API 中很有用,但是如果涉及到很多模型,或者返回的响应数据很复杂,就不太合适了,所以我们更多时候是将转化器作为参数传入响应构建器,通过二者的结合来构建 JSON 响应,通过这种方式,Dingo 底层会自动注册模型类与转化器的映射。

在响应构建器中使用转化器

由于 Dingo 转化器是基于 Fractal 实现的,所以相关的功能实现也很类似,无非是在 Fractal 的基础上做了一些封装而已,下面我们就来看看如何在 Dingo 响应构建器中使用转化器构建复杂一点的 JSON 响应。

单个资源响应

如果响应返回的是单个模型实例的话,可以借助 Fractal 的单个资源转化来实现,在 Dingo 响应构建器中,对应的是 item 方法,第一个参数传入模型实例,第二个参数传入对应的转化器实例来构建响应,正好我们可以通过修改 Api\TaskControllershow 方法来演示这一场景:

public function show($id)
{
    $task = Task::findOrFail($id);
    return $this->response->item($task, new TaskTransformer());
}

由于 item 方法内部会自动注册模型类与转化器之间的映射,所以可以移除之间在 AppServiceProviderboot 方法中显式注册的映射:

app(Factory::class)->register(Task::class, TaskTransformer::class);

在 Postman 中访问该路由,返回结果和之前一致。

引入关联模型

有的时候,我们还需要引入与指定模型实例相关联的关联模型,基于 Fractal 引入关联模型我们在上篇教程已经介绍过,并且编写好了对应的代码,Dingo API 只是对此做了一层封装,但是对开发者来说,却更加方便,只需要在调用 API 接口时通过 include 请求参数指定要返回的关联模型名称即可,但是这个名称需要和对应转化器中的 $availableIncludes 指定名称保持一致,比如这里我们要获取与指定任务相关联的用户信息,可以这样访问 API 接口:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(五) —— 转化器篇(下):结合响应构建器构...

可以看到,我们在请求 URL 中通过设置 include 参数为 user 指定要获取的关联对象,不需要编写任何代码即可在响应中返回对应的关联数据,非常方便。

资源集合响应

如果返回的是多个模型实例,对应的,可以借助 Fractal 的资源集合转化来实现,在 Dingo 响应构建器中,对应的是 collection 方法,第一个参数传入模型实例集合,第二个参数传入转化器实例,我们可以通过编写 Api\TaskControllerindex 方法来演示这一场景:

public function index()
{
    $tasks = Task::all();
    return $this->response->collection($tasks, new TaskTransformer());
}

在 Postman 中,可以通过访问 tasks.index 路由对应 URL 来获取对应的响应数据:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(五) —— 转化器篇(下):结合响应构建器构...

分页响应

通常,如果数据量很大的话,在获取任务列表数据的时候,有分页需求,Fractal 提供了对分页数据的支持,在 Dingo 响应构建器中,对应的是 paginator 方法,传入参数和 collection 方法一样,我们通过分页来改写上一步实现的 index 方法如下:

public function index()
{
    $tasks = Task::paginate();
    return $this->response->paginator($tasks, new TaskTransformer());
}

再次访问任务列表 URL,就可以获取到分页信息了:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(五) —— 转化器篇(下):结合响应构建器构...

以上,就是我们日常比较常见的 API 接口返回数据格式场景了,此外,在构建 API 响应时,可能还会有其它的一些额外需求,比如设置响应头、响应状态码、元数据等,下面我们来看下这些场景下构建响应。

添加额外的响应头

Laravel 框架提供的响应类一样,由于 Dingo 响应构建器提供的是流式接口,所以我们可以通过方法链的方式追加额外的信息到返回的响应实例,比如添加额外的响应头可以这么做:

return $this->response->item($task, new TaskTransformer)->withHeader('Foo', 'Bar');

还可以通过 withHeaders 方法一次添加多个响应头:

return $this->response->item($task, new TaskTransformer())->withHeaders([
    'Foo' => 'Bar',
    'Hello' => 'World'
]);

如果要添加 Cookie 的话,可以通过 cookiewithCookie 方法:

$cookie = new \Symfony\Component\HttpFoundation\Cookie('foo', 'bar');
return $this->response->item($task, new TaskTransformer())->withCookie($cookie);

传入的 Cookie 必须是一个 \Symfony\Component\HttpFoundation\Cookie 对象实例。

设置响应状态码

设置响应状态码可以这么做:

return $this->response->item($task, new TaskTransformer)->setStatusCode(200);

添加元数据

某些转化层可能会使用元数据(meta data),这在你需要提供额外与资源关联的数据时很有用:

return $this->response->item($task, new TaskTransformer)->addMeta('foo', 'bar');

对应返回的数据格式如下:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(五) —— 转化器篇(下):结合响应构建器构...

还可以设置元数据数组替代多个方法链的调用:

$meta = [
    'foo' => 'bar'
];
return $this->response->item($task, new TaskTransformer())->setMeta($meta);

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

游戏引擎架构

游戏引擎架构

[美] Jason Gregory (杰森.格雷戈瑞) / 叶劲峰 / 电子工业出版社 / 2014-1 / 128.00元

《游戏引擎架构》同时涵盖游戏引擎软件开发的理论及实践,并对多方面的题目进行探讨。本书讨论到的概念及技巧实际应用于现实中的游戏工作室,如艺电及顽皮狗。虽然书中采用的例子通常依据一些专门的技术,但是讨论范围远超于某个引擎或API。文中的参考及引用也非常有用,可让读者继续深入游戏开发过程的任何特定方向。 《游戏引擎架构》为一个大学程度的游戏编程课程而编写,但也适合软件工程师、业余爱好者、自学游戏程......一起来看看 《游戏引擎架构》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具