使用JSON Schema验证API响应

API的响应需要约束

目前我们开发Web API的方式是通过定义Open API描述文件来定义请求约束。约束能够保证所有请求参数按照正确的格式和必要性传输,从而规范化输入。这保护了服务端内部的安全——输入约束不变的情况下,输入的值总是合法可期的。

尽管Open API也提供了对Response Body的定义,允许用户描述响应的消息格式,但由于其不具有强制性——语法上可以不写,写了也不与实际返回内容有深入结合,因此无法验证真实API的响应是否符合预期,这也是从一开始不愿写响应体的原因。

而关于验证API响应的重要性,是不言而喻的,截止目前,至少有两个时刻让我有了“如果能够在单元测试就验证响应体格式就好了”的想法。

其一:今年上半年的一次down time,彼时是上线真米视频,其video id要做到可控(手动编写,数位字符串),而原逻辑使用了阿里云生成的video id——32位字符串。使用的方案是将手动生成的video id替换了阿里云video id,结果由于测试上的不周全导致所有视频的video id都被替换,对于那些没有分配手动id的音视频,其video id自然变成了null。而该问题因为机缘巧合对视频无影响,仅对音频产生影响。导致较长时间才发现。回首该问题,出在video id字段的格式上,如果有对响应体做约束——要求video id必须有值,且长度为32位,则该问题能够在单元测试就发现。

其二:呼啦亲子项目已进行了多次迭代,大致如下

  • 初版
  • 增加了呼啦圈,其内容与文章接近,封面图需要记录宽高和媒体类型;为了保持格式一致,原本文章的封面格式也改为如此
  • 首页文章的封面的显示增加多图效果,其它页面保持原有格式不变,且多图效果要求类随机——即要对封面字段格式化输出
  • 创作者中心用于编辑上面多图的选项,因此获取的封面字段要原样输出
  • 每一次升级都要兼容之前的版本

光看文章这一项的元数据,就有下面四种格式

首页文章格式(其中coverSrc用于兼容最初版本、cover用于兼容次初版本API、covers+style是最新版的API需要的字段)

"meta": {
   
    "title": "各国孩子吃什么零食之法国篇",
    "covers": [
        {
   
            "url": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg?x-oss-process=image/auto-orient,1/interlace,1/resize,m_lfit,w_828/quality,q_90/format,jpg",
            "width": 800,
            "height": 600,
            "mediaType": "image"
        }
    ],
    "coverSrc": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg",
    "cover": {
   
        "url": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg?x-oss-process=image/auto-orient,1/interlace,1/resize,m_lfit,w_828/quality,q_90/format,jpg",
        "width": 800,
        "height": 600,
        "mediaType": "image"
    },
    "style": "singleMinImage"
}

普通文章列表页格式(多图显示仅对首页生效,普通列表页保持次初版本格式)

"meta": {
   
    "title": "各国孩子吃什么零食之法国篇",
    "coverSrc": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg",
    "cover": {
   
        "url": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg?x-oss-process=image/auto-orient,1/interlace,1/resize,m_lfit,w_828/quality,q_90/format,jpg",
        "width": 800,
        "height": 600,
        "mediaType": "image"
    }
}

文章详情页格式(多出来了jsVersion和cssVersion)

"meta": {
   
    "title": "各国孩子吃什么零食之法国篇",
    "coverSrc": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg",
    "cover": {
   
        "url": "https://qinzi.static.hulaplanet.com/ttp/editor/94d53aa2e67acaf5bdac445eb1ed2144.jpg?x-oss-process=image/auto-orient,1/interlace,1/resize,m_lfit,w_828/quality,q_90/format,jpg",
        "width": 800,
        "height": 600,
        "mediaType": "image"
    },
    "jsVersion": "awbegiwaubegwug",
    "cssVersion": "weignwoe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值