Laravel & Lumen RESTFul API 扩展包:Dingo API(三) —— Response(响应)

来源:互联网 发布:nodejs用什么数据库 编辑:程序博客网 时间:2024/05/24 00:37

一个API的功能主要是获取请求并返回响应给客户端,响应的格式是多样的,比如JSON,返回响应的方式也是多样的,这取决于当前构建的API的复杂度以及对未来的考量。

返回响应最简单的方式是直接从控制器返回数组或对象,但不是每个响应对象都能保证格式正确,所以你要确保它们实现了ArrayObject或者Illuminate\Support\Contracts\ArrayableInterface接口:

class UserController{    public function index()    {        return User::all();    }}

在本例中,User类继承自Illuminate\Database\Eloquent\Model,这意味着返回的是可以被格式化为数组的数据,当然也可以返回单个用户:

class UserController{    public function show($id)    {        return User::findOrFail($id);    }}

Dingo API会自动将响应格式化为JSON格式并设置Content-Type头为application/json

1、响应构建器

响应构建器提供了平滑的接口以便我们轻松构建更多自定义的响应。响应构建器通常与转换器(Transformer)一起使用。

要使用响应构建器控制器需要使用Dingo\Api\Routing\Helpers trait,为了让每个控制器都可以使用这个trait,我们将其放置在API基类控制器Controller中:

use Dingo\Api\Routing\Helpers;use Illuminate\Routing\Controller;class BaseController extends Controller{    use Helpers;}

现在可以定义一个继承自该控制器的控制器,在这些控制器中可以通过$response属性来访问响应构建器。

数组响应

class UserController extends BaseController{    public function show($id)    {        $user = User::findOrFail($id);        return $this->response->array($user->toArray());    }}

单个Item响应

class UserController extends BaseController{    public function show($id)    {        $user = User::findOrFail($id);        return $this->response->item($user, new UserTransformer);    }}

集合响应

class UserController extends BaseController{    public function index()    {        $users = User::all();        return $this->response->collection($users, new UserTransformer);    }}

分页响应

class UserController extends BaseController{    public function index()    {        $users = User::paginate(25);        return $this->response->paginator($users, new UserTransformer);    }}

无内容响应

return $this->response->noContent();

创建响应

return $this->response->created();

还可以将位置信息作为创建资源的第一个参数:

return $this->response->created($location);

错误响应

你可以使用多种内置错误生成错误响应:

// A generic error with custom message and status code.return $this->response->error('This is an error.', 404);// A not found error with an optional message as the first parameter.return $this->response->errorNotFound();// A bad request error with an optional message as the first parameter.return $this->response->errorBadRequest();// A forbidden error with an optional message as the first parameter.return $this->response->errorForbidden();// An internal error with an optional message as the first parameter.return $this->response->errorInternal();// An unauthorized error with an optional message as the first parameter.return $this->response->errorUnauthorized();

添加额外的响应头

使用了上述方法之后还可以通过添加响应头来自定义响应:

return $this->response->item($user, new UserTransformer)->withHeader('X-Foo', 'Bar');

添加元数据

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

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

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

return $this->response->item($user, new UserTransformer)->setMeta($meta);

设置响应状态码

return $this->response->item($user, new UserTransformer)->setStatusCode(200);

2、自定义响应格式

在安装配置中我们已经简单接触过响应格式,默认情况下Dingo API会自动使用JSON格式并设置相应的Content-Type头。除了JSON之外还有一个JSONP格式,改格式会将响应封装到一个回调中。要注册改格式只需要简单将配置文件(Laravel)或启动文件(Lumen)中的默认JSON格式替换成JSONP即可:

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

或者:

Dingo\Api\Http\Response::addFormatter('json', new Dingo\Api\Http\Response\Format\Jsonp);

默认情况下回调参数默认查询字符串是callback,这可以通过修改构造函数的第一个参数来设置。如果查询字符串不包含任何参数将会返回JSON响应。

你还可以注册并使用自己需要的响应格式,自定义的格式对象需要继承自Dingo\Api\Http\Response\Format\Format类,同时还要实现如下这些方法:formatEloquentModelformatEloquentCollectionformatArray 以及 getContentType

3、Morphing 和 Morphed 事件

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

我们在app/Listeners中为事件创建监听器:

use Dingo\Api\Event\ResponseWasMorphed;class AddPaginationLinksToResponse{    public function handle(ResponseWasMorphed $event)    {        if (isset($event->content['meta']['pagination'])) {            $links = $event->content['meta']['pagination']['links'];            $event->response->headers->set(                'link',                sprintf('<%s>; rel="next", <%s>; rel="prev"', $links['links']['next'], $links['links']['previous'])            );        }    }}

然后通过在EventServiceProvider中注册事件及其对应监听器来监听该事件:

protected $listen = [    'Dingo\Api\Event\ResponseWasMorphed' => [        'App\Listeners\AddPaginationLinksToResponse'    ]];

现在所有包含分页链接的响应也会将这些链接添加到Link头。

注意:目前该功能还在开发阶段,不建议用于生产环境。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕产检医生问的尴尬怎么办 带着节育环做的核磁怎么办 便秘洗肠后最一周未排便怎么办 用了开塞露后肚子疼拉不出来怎么办 冰点脱毛当天用沐浴露洗澡了怎么办 自体脂肪填充脸部但发红又痒怎么办 金矿受伤死亡不给开死亡证明怎么办 手机欠费了导致没信号了怎么办 金立手机指纹硬件无法使用怎么办 试管取卵医生说卵子碎片多怎么办 取卵腹水抽水后尿不通怎么办 手机锁屏密码忘了怎么办求解锁 苹果手表锁屏密码忘记了怎么办 苹果手表锁屏密码忘了怎么办 电脑输密码时点了用户账户怎么办 w7电脑锁屏密码忘记了怎么办 台式电脑w7锁屏密码忘记了怎么办 win7电脑锁屏密码忘记了怎么办 苹果手机4s开机密码忘记了怎么办 苹果4s下载东西忘记密码怎么办 苹果4s不记得开机密码怎么办? 苹果手机id密码忘了怎么办能解锁 苹果5s id密码忘了怎么办? 苹果手机激活锁id忘记了怎么办 苹果刷了机忘了账号无法激活怎么办 三星s7指纹解开锁密码忘了怎么办 索尼手机锁屏密码忘了怎么办 金立手机开机密码忘了怎么办 如果小米手机锁屏密码忘记了怎么办 小米手机锁屏密码忘了怎么办 小米5x忘记了屏保锁屏密码怎么办 htc手机锁屏密码忘了怎么办 苹果7手机解锁密码忘了怎么办 魅族7plus锁屏密码忘了怎么办 捡到苹果手机不知道id密码怎么办 平板不知道id地址和密码怎么办 红米1s刷机变砖了怎么办 车玻璃被鞭炮炸了黑印子怎么办 出轨的事被家人知道后道处传怎么办 村霸霸占土地弱势村民该怎么办? 户户通没有插卡位置信息改变怎么办