(java) restful接口返回值设计

关于restful接口返回值设计有一些疑问,目前我采用的是

Result { status,msg,data}

当status 为 0 时 代表请求成功 data里有返回的数据 为Json格式 msg里没有数据
当status 为 1 时 代表请求失败 data里没有数据 msg里有错误提示语

使用了一段时间发现了几个问题

  • 请求成功的时候 data里的数据格式 定义 需要人为的告诉对方 这个数据的定义的类名,所以想增加一个参数 传入类名 例如: type:OrderDTO 这样对方就可以直接反序列化我已把数据格式定义DTO的jar包挂在nexus上面,但是感觉作为一个接口提供方,平台性质的,感觉这样太调皮了,特别是Ios也没办法用你这样的数据格式,andorid就很方便可以直接用。

  • 请求失败的时候 ,我的msg里统一是英文处理格式,是把国际化放在客户端上面,还是放在后台,这样后台每次都要去改文案提示语,以及多国语言,纠结。

重新看了淘宝,微信,开放平台的设计,都感觉返回值不是很友好,不好统一处理。

例如:

正常返回:

{ "trade_snapshot_get_response":{ "trade":{ } }
}

异常返回:

{ "error_response":{ "code":50, "msg":"Remote service error", "sub_code":"isv.invalid-parameter", "sub_msg":"非法参数" }
}

但是他们都会设置全局的状态码,感觉也没太大的好处,不如直接返回错误信息,干嘛还要状态码。

各位走过路过的朋友,麻烦给点建议。

===========================
更新:

感觉全局状态码很麻烦,要公布一份全局状态码给别人,例如html形式,而且还要维护。不如直接在代码里返回给对方错误信息提示,例如:msg:errorId 代表Id错误 对面根据errorId 提示对应的文案术语。。
感觉比 返回 状态码 40001 代表 Id错误要好一点。。

=================================================
更新:

总感觉用状态码的话,简单是定义接口简单,烦躁的地方是 维护这个状态码 另外 一个接口的可能情况 别人不知道 难道要所有状态码里的异常情况都判断一遍么?微信公众平台,淘宝公众平台就是这样干的,这也太不科学了

推荐你学习 REST 层级划分模型,如下图:

英文版 Richardson Maturity Model
中文版 RMM Level — 对于REST的层级划分模型

我现在使用的Controller返回类型–Result

 // 结果编码 protected final int code; protected final String message; protected final T value; protected final Map<String, Object> extraInfo; protected Resultint code, String message, T value { thiscode, message, value, null; }

code就是使用的http status code. 如果是错误信息的话, 会有一个errorReason, 如

return Result.badReq"phone_existed", "手机号已注册";
return Result.badReq"user_not_found_or_password_error", "用户名或密码错误";

前端若不使用后端的错误提示的话, 可以根据errorReason自定义错误提示。
一个例子:

{ "code": 400, "message": "用户名或密码错误", "errorReason": "user_not_found_or_password_error"
}

另外我们使用了swagger来定义Restful接口, 如下所示:

你可以去百度api store看看,返回大体都是你设计的这种,这说明这已经比较合理经过检验的

个人感觉还是不要传入类名,作为一个平台接口没有必要做这么hack的事情,只兼顾Android没什么意义。而且这么设计的话就意味着前后台必须一起维护,也许暂时用着很爽,但是以后新增新的接口和复用之前的接口都可能会出现问题。
关于请求失败,既然你有国际化的需求,那就应该使用错误码,让客户端决定如何显示。个人感觉接口层的错误信息没必要暴露给用户,只要写到日志就够了。客户端应该负责所有的用户界面显示工作,不应该有可预料的错误信息透明地穿过客户端直接从后端直接传给用户。

只是一些个人意见,欢迎大家批评指正。

建议你去看一下 JSON API,不是说你一定要这么做,但你顾虑的事情显然是有完整且标准化的规范的。

另外,状态为什么不用 HTTP Status Code?HTTP 协议提供了标准化的状态码,想不通为什么很多 API 不去善加利用呢?

既然是restful风格 推荐使用HTTP Status Code

返回类名? JSON是平台无关的,没必要知道是什么类,对于Java来说JSON完全可以当成是Map使用,而且你提供的是API,那么使用者就得按照你设计的去做,就像微信API,他设计成什么样你就得如何处理。
如果你想设计的优美点就用返回码+JSON,错误提示都可有可无,说实话没人在意你的msg,都是根据code去处理,因为很多情况下msg是可变的,虽然模板固定,但是内容可变,比如appKey不存在,有些msg可能直接把appKey放进去 所以是变化的;但是code肯定是不变的,维护不好全局code是你们自身能力的问题,可不能偷懒坑了开发者。

1)Restful接口的要做到平台无关,并且传递的JSON格式数据量要紧凑
2)返回的消息最好带有code和消息说明,code定义不同的范围,表示不同的消息类型及级别;code对应默认的消息描述,有消息说明就用消息说明的

RESTFul的response只要能说明:你请求的结果和状态即可。所以做API的,做好这些,大家都遵守就没啥问题。
譬如

{

"code":0,
"msg":"ok",
"data":[1,2,3],

}

不推荐直接硬编码中文错误提示。可能对方就依赖你的msg信息,API应该全部英文+数字,全局状态码是非常有必要的,这大大增加了你的扩展性。一些不必要的信息不推荐返回,比如api地址啊,这些,新浪好像返回了,但实际上,如果不是那种平台级面向多用户的话,自己维护好API文档就OK了。

还有两种风格也共选择:
1 保持结构的统一,也就是说,就算code是-1(假设系统错误),那么data也返回[]
2 以code为准,这样如果code 是-1,则不显示data,因为没有data嘛,把msg变成errorMsg
可能还有很多其他风格,但是,只要你保持你的API风格统一,基本上没啥大问题了。千万不要一会儿以这个为主,一会儿以那个为主。记住,你是写API的,只要数据完全符合要求,你用啥名字就用啥,不要为这些争执不休。

发表评论

电子邮件地址不会被公开。 必填项已用*标注