前言
本文描述了后端开发服务返回值定制的一些痛点,以及如何使用Gateway 来优雅的解决这些问题
问题一
在我们开发系统的时候,会遇到一些很恶心的问题,对于一个业务对象,针对不一样的场景,对外输出的时候,数据字段上需要过滤。比如:用户信息包括的字段:
- ID
- 名称
- 银行账号
那么对于如下的场景:
- 查看他人信息,展示:ID和名称
- 查看自己信息,展示:所有字段
这个时候就会有很多做法:
- 根据不同场景定制不同对象,copy属性后,返回
- 定制化的Json字段序列化(例如Jackson的View概念)
这个两种做法,做起来都是比较麻烦的,对于后端开发来说,比较麻烦,特别一些比较核心的业务对象有时候很负责,场景很多。
问题二
我们使用网关后,可以使用聚合的功能,聚合返回数据。在有些时候,聚合的返回值有一些对前端不友好,举个例子:
- API-1
这个API返回:
{
"code": 0,
"data": {
"f1": "api1-field1",
"f2": "api1-field2"
}
}
- API-2
这个返回数据:
{
"code": 0,
"data": {
"f1": "api2-field1",
"f2": "api2-field2"
}
}
那么这个聚合API的返回值是:
{
"api1": {
"code": 0,
"data": {
"f1": "api2-field1",
"f2": "api2-field2"
}
},
"api2": {
"code": 0,
"data": {
"f1": "api2-field1",
"f2": "api2-field2"
}
}
}
在这个情况下,前端需要对这个返回值做特殊处理。如果输出这个格式那么对前端更友好,更统一:
{
"code": 0,
"data": {
"api1": {
"f1": "api1-field1",
"f2": "api1-field2"
},
"api2": {
"f1": "api2-field1",
"f2": "api2-field2"
}
}
}
Gateway的RenderTemplate功能
Gateway支持对后端的返回值和聚合结果重新根据模板渲染,用这个功能可以定制返回对象的字段,格式等等。
解决问题一
假设user的API返回值是:
{
"code": 0,
"data": {
"id": 1,
"name": "zhangsan",
"bank": "123456"
}
}
那么我们可以在Gateway上定义2个API分别为:
- /api/users/[0-9]+
使用Gateway的客户端针对这个API设置RenderTemplate:
api := client.GetAPI(apiID)
ab := c.NewAPIBuilder().Use(api)
ab.AddFlatRenderObject("code", "code")
ab.AddRenderObject("data", "id", "data.id", "name", "data.name", "bank", "data.bank")
- /api/public/users/[0-9]+
使用Gateway的客户端针对这个API设置RenderTemplate:
api := client.GetAPI(apiID)
ab := c.NewAPIBuilder().Use(api)
ab.AddFlatRenderObject("code", "code")
ab.AddRenderObject("data", "id", "data.id", "name", "data.name")
我们也可以定制更多输出场景,但是对于后端开发来说,只有一个API。
解决问题二
在聚合API的基础上设置RenderTemplate:
api := client.GetAPI(apiID)
ab := c.NewAPIBuilder().Use(api)
ab.AddFlatRenderObject("code", "api1.code")
ab.AddRenderObject("data", "api1", "api1.data", "api2", "api2.data")
如果在需要定制api1或者api2的data的部分字段可以修改为:
api := client.GetAPI(apiID)
ab := c.NewAPIBuilder().Use(api)
ab.AddFlatRenderObject("code", "api1.code")
ab.AddRenderObject("data", "api1", "api1.data.field1,api1.data.field2", "api2", "api2.data")
总结
利用Gateway的renderTemplate功能能够实现后台API返回值的定制化功能,并且这些都是动态的,可以随时调整。解放了后端的部分开发工作。