Gateway杂谈:定制化输出API结果

前言

本文描述了后端开发服务返回值定制的一些痛点,以及如何使用Gateway 来优雅的解决这些问题

问题一

在我们开发系统的时候,会遇到一些很恶心的问题,对于一个业务对象,针对不一样的场景,对外输出的时候,数据字段上需要过滤。比如:用户信息包括的字段:

  • ID
  • 名称
  • 银行账号

那么对于如下的场景:

  • 查看他人信息,展示:ID和名称
  • 查看自己信息,展示:所有字段

这个时候就会有很多做法:

  1. 根据不同场景定制不同对象,copy属性后,返回
  2. 定制化的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返回值的定制化功能,并且这些都是动态的,可以随时调整。解放了后端的部分开发工作。

了解更多Gateway特性

更多特性

猜你喜欢

转载自my.oschina.net/u/2244142/blog/1620161