Spring Boot接口设计规范
接口参数处理及统一结果响应
1、接口参数处理
1、普通参数接收
这种参数接收方式是比较常见的,由于是GET请求方式,所以在传参时直接在路径后拼接参数和参数值即可。
例如:localhost:8080/api/product/list?key1=value1&key2=value2
/**
* 商品列表 - 普通参数接收
* @return 统一返回对象
*/
@RequestMapping(value = "/product/list",method = RequestMethod.GET)
public Result list(
@RequestParam(required = false) String goodsStatus,
@RequestParam(required = false) String goodName,
@RequestParam(required = false) Integer pageNum,
@RequestParam(required = false) Integer pageSize){
// 业务逻辑略....
}
2、路径参数接收
在开发过程中会出现部分接口设计时采用将参数拼入路径中的方式,当只需要一个参数时,可以考虑路径参数接收这种接口设计方式。这种请求方式与普通参数接收方式没有很大的区别,个人习惯。。。
例如:像根据订单号查询,这个时候可以将接口设计成/product/1024,在接口方法的参数列表中使用@PathVariable注解对订单号进行接收。
/**
* 根据商品id获取商品详情
* @return 统一返回对象
*/
@RequestMapping(value = "/product/{id}",method = RequestMethod.GET)
public Result goods(@PathVariable("id") Integer productId){
// 业务逻辑略....
}
3、对象参数接收
在进行接口开发的过程中,项目中的POST或者PUT方法类型的接口,基本上都是以对象形式来接收参数的。
例如在登录接口中,前端在请求体中传递JSON格式的请求参数,后端使用@RequestBody注解对前端传递过来的JSON数据进行接收,并将参数转换成对应的实体类。
@RequestMapping(value = "/admin/login", method = RequestMethod.POST)
public Result<String> login(
@RequestBody @Valid AdminLoginParam adminLoginParam){
// 业务逻辑略....
}
AdminLoginParam
@Data
public class AdminLoginParam implements Serializable {
@NotEmpty(message = "登录名不能为空")
private String userName;
@NotEmpty(message = "密码不能为空")
private String password;
}
这样当前端通过调用/admin/login接口,并传递如下json数据给后端,后端就会接收并处理登录流程了。
{
"username" : "panpan",
"password" : "123123"
}
为了统一数据格式,前端传递数据的过程中,需要统一在请求头中将Content-Type设置为application/json
4、复杂对象接收
在开发过程中避免不了会出现一些复杂的对象,这些复杂对象往往都是一个对象中包含另外一个实体对象,或者包含一组对象(List params)
这种复杂对象接收方式与对象参数接收的方式一样,前端在传递的时候只需要在json串中嵌套一层json对象。后端接收参数时封装一个嵌套对象即可
@PostMapping("/saveOrder")
public Result<String> saveOrder(
@Parameter(description = "订单参数") @RequestBody SaveOrderParam saveOrderParam){
// 业务逻辑略....
}
SaveOrderParam
@Data
public class SaveOrderParam implements Serializable {
// 订单项id数组
private Long[] cartItemIds;
// 地址id
private Long addressId;
}
2、统一结果响应
为了保证所有接口响应数据格式的统一,这样可以大大减少接口响应的工作量,方便前端同学使用接口。
/**
* 统一返回对象
*
* @author supanpan
* @create_date 2023-11-19 11:03
*/
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
//业务码,比如成功、失败、权限不足等 code,可自行定义
private int resultCode;
//返回信息,后端在进行业务处理后返回给前端一个提示信息,可自行定义
private String message;
//数据结果,泛型,可以是列表、单个对象、数字、布尔值等
private T data;
public Result() {
}
public Result(int resultCode, String message) {
this.resultCode = resultCode;
this.message = message;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"resultCode=" + resultCode +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
封装响应结果生成工具类
/**
* 响应结果生成工具
*
* @author supanpan
* @create_date 2023-11-19 11:05
*/
public class ResultGenerator {
private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
private static final String DEFAULT_FAIL_MESSAGE = "FAIL";
private static final int RESULT_CODE_SUCCESS = 200;
private static final int RESULT_CODE_SERVER_ERROR = 500;
public static Result genSuccessResult() {
Result result = new Result();
result.setResultCode(RESULT_CODE_SUCCESS);
result.setMessage(DEFAULT_SUCCESS_MESSAGE);
return result;
}
public static Result genSuccessResult(String message) {
Result result = new Result();
result.setResultCode(RESULT_CODE_SUCCESS);
result.setMessage(message);
return result;
}
public static Result genSuccessResult(Object data) {
Result result = new Result();
result.setResultCode(RESULT_CODE_SUCCESS);
result.setMessage(DEFAULT_SUCCESS_MESSAGE);
result.setData(data);
return result;
}
public static Result genFailResult(String message) {
Result result = new Result();
result.setResultCode(RESULT_CODE_SERVER_ERROR);
if (!StringUtils.hasText(message)) {
result.setMessage(DEFAULT_FAIL_MESSAGE);
} else {
result.setMessage(message);
}
return result;
}
public static Result genErrorResult(int code, String message) {
Result result = new Result();
result.setResultCode(code);
result.setMessage(message);
return result;
}
}
使用示例:
/**
* 商品列表
* @return 统一返回对象
*/
@RequestMapping(value = "/product/list",method = RequestMethod.GET)
public Result list(
@RequestParam(required = false) String goodsStatus,
@RequestParam(required = false) String goodName,
@RequestParam(required = false) Integer pageNum,
@RequestParam(required = false) Integer pageSize){
// 返回数据对象
Object resultData = new Object();
return ResultGenerator.genSuccessResult(resultData);
}