【Java学习】API接口数据规范

在日常开发中,一个优雅的API,必须提供简单明了的响应值,然后根据状态码就可以大概知道问题的所在。这里主要整理一下HTTP状态码和自定义状态码。

1、HTTP状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。

常见的HTTP状态码有:

200-请求成功。

301-资源(网页等)被永久转移到其它URL。

403-服务器拒绝访问。验证身份通过了,但是资源没有权限进行操作。

404-请求资源(网页等)不存在。

500-内部服务器错误。

504-网关超时。服务器作为网关或代理,但是没有及时从上游服务器收到请求。

2、HTTP状态码分类

HTTP状态码可以分为5类:消息响应、成功响应、重定向、客户端错误、服务器错误。

3、自定义响应状态码规范

后端返回给前端一般使用json格式,定义如下:

{
    #返回状态码
    Code:integer,
    #返回信息描述
    message:string,
    #返回值
  	data:object
}
复制代码

3.1、返回接口

public interface IResultStatus {
    /**
     * 状态码
     * @return
     */
    Integer errorCode();
    /**
     * 异常信息
     * @return
     */
    String errorMsg();
}
复制代码

3.2、状态码枚举:

public enum ResultStatus implements IResultStatus {
    /**
     * 状态码及对应信息
     */
    //成功状态码
    SUCCESS(0, "执行成功"),
    //参数错误:1001~1999
    PARAM_IS_INVALID(1001, "参数无效"),
    PARAM_IS_BLANK(1002, "参数为空"),
    PARAM_TYPE_BIND_ERROR(1003, "参数类型错误"),
    //用户错误:2001~2999
    USER_LOGIN_ERROR(2001, "账号不存在或密码错误"),
    USER_ACCOUNT_FORBIDDEN(2002, "账户已被禁用"),
    USER_NOT_EXIST(2003, "用户不存在");
    private int errorCode;
    private String errorMsg;
    ResultStatus(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }
    @Override
    public Integer errorCode() {
        return errorCode;
    }
    @Override
    public String errorMsg() {
        return errorMsg;
    }
}
复制代码

状态码和信息就会一一对应,比较好维护。这样前端同事在得到返回值后,根据状态码就可以知道,大概是什么错误,再根据message相关的信息描述,可以快速定位。

3.3、返回数据体

json格式,根据不同的业务有不同的json体,可以设计一个返回体类Result

@Data
public class Result<T> {
    private Integer code;
    private String message;
    private Object data;
    public Result(ResultStatus restStatus, Object data) {
        this.code = restStatus.errorCode();
        this.message = restStatus.errorMsg();
        this.data = data;
    }
    /**
     * 业务成功返回业务代码和描述信息
     */
    public static Result<Void> success() {
        return new Result<Void>(ResultStatus.SUCCESS, null);
    }
    /**
     * 业务成功返回业务代码,描述和返回的参数
     */
    public static <T> Result<T> success(T data) {
        return new Result<T>(ResultStatus.SUCCESS, data);
    }
    /**
     * 业务成功返回业务代码,描述和返回的参数
     */
    public static <T> Result<T> success(ResultStatus resultStatus, T data) {
        if (resultStatus == null) {
            return success(data);
        }
        return new Result<T>(resultStatus, data);
    }
    /**
     * 业务异常返回业务代码和描述信息
     */
    public static <T> Result<T> failure() {
        return new Result<T>(ResultStatus.PARAM_TYPE_BIND_ERROR, null);
    }
    /**
     * 业务异常返回业务代码,描述和返回的参数
     */
    public static <T> Result<T> failure(ResultStatus resultStatus) {
        return failure(resultStatus, null);
    }
    /**
     * 业务异常返回业务代码,描述和返回的参数
     */
    public static <T> Result<T> failure(ResultStatus resultStatus, T data) {
        if (resultStatus == null) {
            return new Result<T>(ResultStatus.PARAM_IS_INVALID, null);
        }
        return new Result<T>(resultStatus, data);
    }
}
复制代码

3.4、返回体测试

@RestController
@RequestMapping("/api/demo2")
public class Demo2Controller {
    private static final HashMap<String, Object> INFO;
    static {
        INFO = new HashMap<>();
        INFO.put("name", "张三");
        INFO.put("age", "25");
    }
    @GetMapping("/getInfo")
    public Map<String, Object> getInfo() {
        return INFO;
    }
    @GetMapping("/getInfoResult")
    public Result<Map<String, Object>> getInfoResult() {
        return Result.success(INFO);
    }
}
复制代码

结果参考:

猜你喜欢

转载自juejin.im/post/7085264361945727007