restful返回码规范(数据为null如何处理)

Restful接口,数据为null如何处理背景

一天刚哥气冲冲的找我说:“阿水,关于前后端接口定义!后端返回的数据格式必须和YAPI定义的接口一致, 包括数据字段,数据类型!这条有么”

注:刚哥是发的文字,但是根据我与他共事多年对他的了解,他一定是气冲冲的打的这段文字。

细了解后,才知道具体场景是,如果一个接口定义返回的json是十个字段,其中5个字段没有值,后端返回的json中是把这5个没有值的key给移除了。

那到底应该移除,还是保留key,但是其值为null呢。我一时拿不定主意,于是找了一些业界的RESTful接口定义。

业界实现

•腾讯开放平台:如果数据为null,则不传key,但在其接口定义中明确说明哪些情况下不传key。参见https://wiki.open.qq.com/wiki/v3/user/get_info。

•stripe:其api设计是即便value为null,仍会传key,如果是数组对象,则传空数组[]。•github:经过验证,如果为null,会传对应的key。

•google:google的api建议移除空的或null值,参见 https://google.github.io/styleguide/jsoncstyleguide.xml#Empty/Null_Property_Values•原文:If a property is optional or has an empty or null value, consider dropping the property from the JSON, unless there's a strong semantic reason for its existence

•阿里:其Java开发手册(嵩山版)第一章第十节【前后端规约】中定义:【强制】前后端数据列表相关的接口返回,如果为空,则返回空数组[]或空集合{}。说明:此条约定有利于数据层面上的协作更加高效,减少前端很多琐碎的 null 判断。

•注:其只针对列表数据做了定义,没有对通用的json处理做定义。但可引申为其接口定义要考虑减少前端很多琐碎的 null 判断。

•但是阿里出品的Fastjon的默认实现是移除value为null的key,不过在其SerializerFeature中有丰富的配置可定义,如WriteNullListAsEmpty、WriteNullStringAsEmpty,但是不支持将null object转为{}。

也问了一下阿里和京东等公司工作的朋友,有一人明确回复不传,其余均说是没有明确定义。

考虑因素

•基本类型如何处理,基本类型一定是有值的,无需特殊考虑。•包装类型(如Integer)如何处理,Integer为null时有三种情况,去掉key、传key:null或者传key:0

•字符串处理与Integer处理应保持一致。

•数组如何处理,去掉Key,传array:null或者传array:[]•序列化和反序列化时的语义一致性

•如果你允许response中返回null,则应该允许request提交null。•java和javascript的json处理的一致性

•如果是java,通过json串反序列化为pojo时,即便没有相应的key,pojo中的key仍会存在

•javascript不是一个强类型的语言,通过JSON.parse转为js对象时,如果没有key,则object.{key} === undefined,与null含义相近但不同义。

•你的核心诉求是什么•如果是访问量大,optional字段较大的场景,那毫无疑问应该移除value为null的键值,这样可以降低网络消耗,提升系统效率•对接口使用者友好

结论

•对于Response的json数据,key:null 与 没有key 应该有相同的语义,代表该值不存在。

•如果是Http patch的Request的json数据,key:null代表删除该数据,没有key代表没有变化。这也是rfc7396对于 JSON Merge Patch 的定义。参见https://datatracker.ietf.org/doc/html/rfc7396。

•Integer、Boolean如果没有值, 不应该将Integer转为0,Boolean转为false。因为二者语义不一样。举个栗子,性别代码值选择,1代表男,2代表女,空(null)代表此项没有值,如果默认为0,则可能与原有值冲突,而且相当于你在json处理时给性别赋予了默认值。包括金额这种数值字段,传成0的话,语义就更不一样了,前端是渲染成0还是渲染成空。所以尽量不要给Integer和Boolean转成0和false的默认值。•String的null和空字符串,在业界是有共识的,代表blank,所以二者皆可。

•null数组应该转为[],减少前端冗余的嵌套的null判断。fastjson可以通过SerializerFeature.WriteNullListAsEmpty来进行设置。•其它空对象,是传null还是传{}。这种情况,要么不传key,要么传key:null,如果要传{},对象嵌套怎么办,按照定义,就应该传成parent:{son:{}},因为son也是个对象,要传{}。如果传成parent:{son:{}},语义已经不可定义了,它是空对象还是非空对象,你要判断parent对象是否存在,就得是所有其子子孙孙对象都是{}空对象,它才是空。

•javascipt也支持类似java的optioanl操作,语法为obj?.obj.properties,加一个?就是optional链式调用。参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining。

restful返回码规范(数据为null如何处理)(1)

参考资料

•https://coderwall.com/p/gbxelq/simple-rules-for-a-sane-restful-api-design

•https://github.com/WP-API/WP-API/issues/2657

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页