数据响应
从 v3.17.0 开始,框架添加了 ServerResponse
和 HttpServerResponse
的实现。
通过这个功能,可以定制服务端的响应成功和失败时的通用格式,规范整个返回逻辑。
Http 通用响应
在 koa 场景下,一般都会处理一些逻辑,最后返回一个结果。在此过程中,会出现返回成功和失败的情况。
最为常见实现会在 ctx
增加一些方法,包括数据后返回。
import { Controller, Get, Inject } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
@Controller('/')
export class HomeController {
@Inject()
ctx: Context;
@Get('/')
async home() {
try {
// ...
return this.ctx.ok(/*...*/);
} catch (err) {
return this.ctx.fail(/*...*/);
}
}
}
也有人会在 Web 中间件中处理成功的返回,在错误过滤器中处理失败的返回。
为了解决这类代码难以统一维护的问题,框架提供了一套统一返回的方案。
我们以最为常见的返回 JSON 数据为例。
通过创建 HttpServerResponse
实例后,调用 json()
方法,链式返回数据。
import { Controller, Get, Inject, HttpServerResponse } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
@Controller('/')
export class HomeController {
@Inject()
ctx: Context;
@Get('/success')
async home() {
return new HttpServerResponse(this.ctx).success().json({
// ...
});
}
@Get('/fail')
async home2() {
return new HttpServerResponse(this.ctx).fail().json({
// ...
});
}
}
默认情况下,HttpServerResponse
在成功和失败的场景上会提供 JSON 的通用包裹结构。
比如在成功的场景下,接收到的数据如下。
{
success: 'true',
data: //...
}
而在失败的场景下,接收到的数据如下。
{
success: 'false',
message: //...
}
注意,json()
方法是数据设置的方法,必须在最后一个调用。
常用的响应格式
HttpServerResponse
需要传递一个当前请求的上下文对象 ctx
才能实例化。
const serverResponse = new HttpServerResponse(this.ctx);
之后以链式的形式进行调用。
// json
serverResponse.json({
a: 1,
});
// text
serverResponse.text('abcde');
// blob
serverResponse.blob(Buffer.from('hello world'));
除了设置数据的方法,还提供了一些其他的快捷方法可以组合使用。
// status
serverResponse.status(200).text('abcde');
// header
serverResponse.header('Content-Type', 'text/html').text('<div>hello</div>');
// headers
serverResponse.headers({
'Content-Type': 'text/plain',
'Content-Length': '100'
}).text('a'.repeat(100));
响应模版
针对不同的设置数据的方法,框架提供了不同模版以供用户自定义。
比如 json()
方法的模版如下。
class ServerResponse {
// ...
static JSON_TPL = (data: Record<any, any>, isSuccess: boolean): unknown => {
if (isSuccess) {
return {
success: 'true',
data,
};
} else {
return {
success: 'false',
message: data || 'fail',
};
}
};
}
我们可以将全局的模版进行覆盖达到自定义的目的。
HttpServerResponse.JSON_TPL = (data, isSuccess) => {
if (isSuccess) {
// ...
} else {
// ...
}
};