在日常开发中,我们总会写各种各样的接口,尤其是在移动互联网,分布式、微服务盛行的当下,绝大部分项目都采用的微服务框架和前后端分离方式来开发,后端工程师能写出优雅接口代码无疑是前端工程师的一个福音,一个优雅的接口可以拥有良好的可读性,而且在接口出现问题时也可以及时的排查错误原因。那么今天就给大家分享一下大聪明在开发接口时的一些心得。
为了确保不同系统/模块间的数据交互,需要事先约定好通讯协议,如:TCP、HTTP、HTTPS协议。为了确保数据交互安全,建议使用HTTPS协议。
作为接口路径,为了方便清晰的区分来自不同的系统,可以采用不同系统/模块名作为接口路径前缀,咱们举个例子:
为了便于后期接口的升级和维护,我们可以在接口路径中加入版本号,便于我们区分和管理接口,从而提升多版本接口的可维护性。不知各位小伙伴有没有留意过,很多框架(比如:Eureka)对外提供的 API 接口中都带有版本号(接口路径中添加类似"v1"、"v2"等版本号)。所以我们在开发接口的时候也可以在接口路径中增加版本号标识,例如 /xx/v1/xx、/xx/v2/xx。
接口命名和 Java 命名规范一样,遵守一个优雅的接口命名规范,不仅可以增强接口的可读性,而且还会让开发人员之间减少很多不必要的口舌之争(要是接口写的太烂导致开发人员看不懂,备不住就直接爆粗口了)。
我们可以结合上文中写到的【接口路径规范】和【版本控制规范】,外加具体接口命名的方式来编写接口的请求路径。这里建议各位小伙伴在给接口命名的时候也要规范一些,这里我们可以使用“驼峰命名法”按照实现接口的业务类型、业务场景等命名(有必要时可采取多级目录命名,但目录不宜过长,两级目录较为适宜),比如:/user/v1/sys/login,代表的就是版本号为v1的用户服务模块的系统登录接口。在具体接口命名,我们通常会使用以下两种方式
统一规范返回数据的格式,对己对彼都有好处,此处以json格式为例。返回数据应包含:返回状态码、返回状态信息、具体数据。格式如下
{
"status":"xxx",
"msg":"xxx",
"data": {
//json格式的具体数据
}
}
上面我们提到了状态码,那么我们再具体的谈一谈关于状态码的规范。一个优雅的接口,给我们提供了简洁明了的状态码,根据状态码就可以让我们快速的定位问题根源所在。我们采用 Http 的状态码进行数据封装,其中状态码为 200 就表示请求成功,状态码为 4xx 就表示客户端错误,状态码为 5xx 就表示服务器内部发生错误。状态码设计参考如下:
public enum CodeEnum {
// 根据具体业务需求进行添加
SUCCESS(200,"请求成功"),
ERROR_PATH(404,"请求地址未找到"),
ERROR_SERVER(500,"服务器内部发生错误");
private int code;
private String message;
CodeEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
我们刚刚也提到了“返回数据应包含:返回状态码、返回状态信息、具体数据”,那么在这里也给大家贴上一个本人常用的返回结果类及其常用方法
public class AjaxResult extends HashMap<String, Object>{
private static final long serialVersionUID = 1L;
/** 状态码 */
public static final String CODE_TAG = "code";
/** 返回内容 */
public static final String MSG_TAG = "msg";
/** 数据对象 */
public static final String DATA_TAG = "data";
/**
* 状态类型
*/
public enum Type
{
/** 成功 */
SUCCESS(0),
/** 警告 */
WARN(301),
/** 错误 */
ERROR(500);
private final int value;
Type(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
/**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/
public AjaxResult()
{
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param type 状态类型
* @param msg 返回内容
*/
public AjaxResult(Type type, String msg)
{
super.put(CODE_TAG, type.value);
super.put(MSG_TAG, msg);
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param type 状态类型
* @param msg 返回内容
* @param data 数据对象
*/
public AjaxResult(Type type, String msg, Object data)
{
super.put(CODE_TAG, type.value);
super.put(MSG_TAG, msg);
if (StringUtils.isNotNull(data))
{
super.put(DATA_TAG, data);
}
}
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult success()
{
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static AjaxResult success(Object data)
{
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult success(String msg)
{
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static AjaxResult success(String msg, Object data)
{
return new AjaxResult(Type.SUCCESS, msg, data);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg)
{
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult warn(String msg, Object data)
{
return new AjaxResult(Type.WARN, msg, data);
}
/**
* 返回错误消息
*
* @return
*/
public static AjaxResult error()
{
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult error(String msg)
{
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult error(String msg, Object data)
{
return new AjaxResult(Type.ERROR, msg, data);
}
}
本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨
希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)
如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。
你在被打击时,记起你的珍贵,抵抗恶意;
你在迷茫时,坚信你的珍贵,抛开蜚语;
爱你所爱 行你所行 听从你心 无问东西