# Code Review
主题:后端接口规范 日期:2024年6月11日 参加人:OSCE项目组 主持人:闫乃新
背景: 拆分微服务后 不可避免各个项目之间相互调用 如何提高接口调用的方便与高效
# 一. 接口规范
使用JSR303校验参数 并写出每个字段的含义
# 1.入参对象
使用@NotBlank
、@NotNull
、@NotEmpty
等注解
@Data
public class StuDTO implements Serializable {
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
private String names;
/**
* 数量
*/
@NotNull(message = "数量不能为空")
@Max(value = 20, message = "数量不能超过20")
@Min(value = 1, message = "数量不能小于1")
private Integer num;
}
# 2.接口
在Controller层中接口中增加@Validated
使其生效
@PostMapping("/addExam")
public AjaxResult addStu(@RequestBody @Validated StuDTO dto) {
Long stuId = stuService.addStu(dto);
}
# 3.Service业务层
在Service层增加@Validated
在接口上增加@Valid
使其生效
@Validated
@Service("stuService")
public class StuService {
public Long addStu(@Valid StuDTO dto) {
return stuService.addStu(dto);
}
}
# 二、批量对象新增时增加businessId业务字段
场景: A系统(服务)调用B系统(服务)的批量新增接口 A系统需要拿到返回数据后继续处理 其中需要拿到B系统返回的主键Id
原因: A系统(服务) 无法确保B系统(服务)返回的数据是否与传入的数据顺序保持一直 需要再次循环比对才能确保数据的一致性后才能拿到当前数据的主键Id进行后续业务,因此加入一个businessId业务字段
- A系统(服务)调用B系统(服务)时每个对象自行生成一个Id
- B系统(服务)返回结果时businessId原封不动的返回
- A系统(服务)根据businessId业务字段进行比对 会大大减少循环比对一致性的难度
原先:
@Data
public class StuDTO implements Serializable {
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
private String names;
/**
* 数量
*/
@NotNull(message = "数量不能为空")
@Max(value = 20, message = "数量不能超过20")
@Min(value = 1, message = "数量不能小于1")
private Integer num;
}
优化后:
@Data
public class StuDTO implements Serializable {
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
private String names;
/**
* 数量
*/
@NotNull(message = "数量不能为空")
@Max(value = 20, message = "数量不能超过20")
@Min(value = 1, message = "数量不能小于1")
private Integer num;
@NotNull(message = "业务Id不能为空")
private Integer businessId;
}
# 三、Feign接口规范
Feign 提供接口时 也使用 通用的返回结果类AjaxResult<T>
好处与理由:
- 统一的数据格式:通过使用 AjaxResult
,可以确保所有 Feign 接口返回的数据格式是一致的。 这有助于调用方理解和处理返回的数据。 - 错误处理标准化:AjaxResult
可以包含错误码、错误消息等信息, 这使得调用方能够更容易地处理错误情况。无论哪个 Feign 接口返回错误,客户端都可以使用相同的逻辑来处理 - 易于扩展:如果将来需要向返回结果中添加新的信息(例如,添加跟踪 ID 或处理时间),
只需修改 AjaxResult
类即可,而不需要修改每个 Feign 接口。
优化前:
public interface StuFeign {
@GetMapping("/feign/getStuList")
List<StuInfoVO> getStuList();
}
优化后:
public interface StuFeign {
@GetMapping("/feign/getStuList")
AjaxResult<List<StuInfoVO>> getStuList();
}
# 四、客户端不可信原则
服务端验证则是为了确保数据的安全性和系统的完整性。即使客户端进行了验证,用户仍然可以通过修改客户端代码或者直接调服务端API绕过这些验证
因此 最终的验证应该是服务端的验证,服务端的验证只是为了减少用户输入的错误,提高用户体验。
eg: 时间(到时间不可修改)
- 用户可以通过更改系统时间,来绕过前端校验
- 用户在结束时间前挂机,当前时间大于结束时间,用户不刷新仍可以修改
- 用户在结束时间后 通过页面把
disabled:disabled
删掉后 仍可以出发点击事件