Files
ruoyi-vue-pro/.cursor/rules/api-design-standards.mdc

469 lines
13 KiB
Plaintext

# API 设计规范
## RESTful API 设计原则
### URL 设计规范
```
/{应用类型}-api/{模块}/{业务对象}/{操作}
示例:
/admin-api/system/user/create # 管理后台创建用户
/admin-api/system/user/page # 管理后台用户分页
/app-api/member/user/profile # 用户端获取个人信息
```
### HTTP 方法使用
```http
GET /admin-api/system/user/get # 获取单个资源
GET /admin-api/system/user/page # 获取资源列表(分页)
GET /admin-api/system/user/list # 获取资源列表(不分页)
POST /admin-api/system/user/create # 创建资源
PUT /admin-api/system/user/update # 更新资源
DELETE /admin-api/system/user/delete # 删除资源
```
### 应用类型前缀
- **admin-api**: 管理后台接口
- **app-api**: 用户端 APP 接口
- **mp-api**: 微信小程序接口
## 统一响应格式
### 成功响应
```json
{
"code": 0,
"data": {
"id": 1,
"username": "admin",
"nickname": "管理员"
},
"msg": ""
}
```
### 错误响应
```json
{
"code": 1002001001,
"data": null,
"msg": "用户不存在"
}
```
### 分页响应
```json
{
"code": 0,
"data": {
"list": [
{
"id": 1,
"username": "admin"
}
],
"total": 100
},
"msg": ""
}
```
## Controller 层实现规范
### 标准 Controller 结构
```java
@RestController
@RequestMapping("/admin-api/system/user")
@Api(tags = "管理后台 - 用户管理")
@Validated
public class UserController {
@Resource
private UserService userService;
@PostMapping("/create")
@ApiOperation("创建用户")
@PreAuthorize("@ss.hasPermission('system:user:create')")
@OperateLog(type = CREATE)
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO reqVO) {
return success(userService.createUser(reqVO));
}
@PutMapping("/update")
@ApiOperation("修改用户")
@PreAuthorize("@ss.hasPermission('system:user:update')")
@OperateLog(type = UPDATE)
public CommonResult<Boolean> updateUser(@Valid @RequestBody UserUpdateReqVO reqVO) {
userService.updateUser(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除用户")
@PreAuthorize("@ss.hasPermission('system:user:delete')")
@OperateLog(type = DELETE)
public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id) {
userService.deleteUser(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得用户")
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<UserRespVO> getUser(@RequestParam("id") Long id) {
UserDO user = userService.getUser(id);
return success(UserConvert.INSTANCE.convert(user));
}
@GetMapping("/page")
@ApiOperation("获得用户分页")
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<PageResult<UserRespVO>> getUserPage(@Valid UserPageReqVO reqVO) {
PageResult<UserDO> pageResult = userService.getUserPage(reqVO);
return success(UserConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/list")
@ApiOperation("获得用户列表")
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<List<UserRespVO>> getUserList(@Valid UserListReqVO reqVO) {
List<UserDO> list = userService.getUserList(reqVO);
return success(UserConvert.INSTANCE.convertList(list));
}
}
```
### 必备注解使用
```java
// 类级别注解
@RestController // 声明为REST控制器
@RequestMapping("/admin-api/system/user") // 请求路径映射
@Api(tags = "管理后台 - 用户管理") // API文档分组
@Validated // 启用参数校验
// 方法级别注解
@PostMapping("/create") // HTTP方法映射
@ApiOperation("创建用户") // API文档说明
@PreAuthorize("@ss.hasPermission('system:user:create')") // 权限控制
@OperateLog(type = CREATE) // 操作日志
```
## 请求参数规范
### 创建请求 VO
```java
@Data
@ApiModel("用户创建 Request VO")
public class UserCreateReqVO {
@ApiModelProperty(value = "用户账号", required = true, example = "admin")
@NotBlank(message = "用户账号不能为空")
@Size(max = 30, message = "用户账号长度不能超过30个字符")
private String username;
@ApiModelProperty(value = "用户昵称", required = true, example = "管理员")
@NotBlank(message = "用户昵称不能为空")
@Size(max = 30, message = "用户昵称长度不能超过30个字符")
private String nickname;
@ApiModelProperty(value = "用户邮箱", example = "admin@example.com")
@Email(message = "邮箱格式不正确")
@Size(max = 50, message = "邮箱长度不能超过50个字符")
private String email;
@ApiModelProperty(value = "手机号码", example = "15601691300")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
private String mobile;
@ApiModelProperty(value = "用户性别", example = "1")
@InEnum(CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer sex;
@ApiModelProperty(value = "部门ID", example = "1")
@NotNull(message = "部门不能为空")
private Long deptId;
@ApiModelProperty(value = "岗位编号数组", example = "1")
private Set<Long> postIds;
@ApiModelProperty(value = "用户角色编号数组", example = "1")
private Set<Long> roleIds;
}
```
### 更新请求 VO
```java
@Data
@ApiModel("用户更新 Request VO")
public class UserUpdateReqVO {
@ApiModelProperty(value = "用户编号", required = true, example = "1")
@NotNull(message = "用户编号不能为空")
private Long id;
// 其他字段与创建请求相同...
}
```
### 分页查询 VO
```java
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("用户分页 Request VO")
public class UserPageReqVO extends PageParam {
@ApiModelProperty(value = "用户账号", example = "admin")
private String username;
@ApiModelProperty(value = "手机号码", example = "15601691300")
private String mobile;
@ApiModelProperty(value = "展示状态", example = "1")
@InEnum(CommonStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
@ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@ApiModelProperty(value = "部门编号", example = "1")
private Long deptId;
}
```
## 响应参数规范
### 响应 VO
```java
@Data
@ApiModel("用户信息 Response VO")
public class UserRespVO {
@ApiModelProperty(value = "用户编号", example = "1")
private Long id;
@ApiModelProperty(value = "用户账号", example = "admin")
private String username;
@ApiModelProperty(value = "用户昵称", example = "管理员")
private String nickname;
@ApiModelProperty(value = "用户邮箱", example = "admin@example.com")
private String email;
@ApiModelProperty(value = "手机号码", example = "15601691300")
private String mobile;
@ApiModelProperty(value = "用户性别", example = "1")
private Integer sex;
@ApiModelProperty(value = "用户头像", example = "https://www.example.com/avatar.jpg")
private String avatar;
@ApiModelProperty(value = "帐号状态", example = "1")
private Integer status;
@ApiModelProperty(value = "最后登录IP", example = "192.168.1.1")
private String loginIp;
@ApiModelProperty(value = "最后登录时间", example = "2022-01-01 00:00:00")
private LocalDateTime loginDate;
@ApiModelProperty(value = "创建时间", example = "2022-01-01 00:00:00")
private LocalDateTime createTime;
/**
* 所属角色
*/
private Set<Long> roleIds;
/**
* 所属岗位
*/
private Set<Long> postIds;
/**
* 所属部门
*/
@ApiModelProperty(value = "部门编号", example = "1")
private Long deptId;
}
```
## 参数校验规范
### 常用校验注解
```java
// 非空校验
@NotNull(message = "ID不能为空")
@NotBlank(message = "用户名不能为空")
@NotEmpty(message = "角色列表不能为空")
// 长度校验
@Size(min = 2, max = 30, message = "用户名长度必须在2-30字符之间")
@Length(max = 50, message = "邮箱长度不能超过50个字符")
// 格式校验
@Email(message = "邮箱格式不正确")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
// 数值校验
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
@Range(min = 1, max = 100, message = "百分比必须在1-100之间")
// 自定义校验
@InEnum(CommonStatusEnum.class, message = "状态必须是 {value}")
```
### 分组校验
```java
// 定义校验分组
public interface AddGroup {}
public interface UpdateGroup {}
// 在字段上使用分组
@NotNull(groups = UpdateGroup.class, message = "ID不能为空")
private Long id;
@NotBlank(groups = {AddGroup.class, UpdateGroup.class}, message = "用户名不能为空")
private String username;
// 在Controller中指定分组
@PostMapping("/create")
public CommonResult<Long> createUser(@Validated(AddGroup.class) @RequestBody UserSaveReqVO reqVO) {
return success(userService.createUser(reqVO));
}
```
## 异常处理规范
### 全局异常处理
```java
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理业务异常
*/
@ExceptionHandler(ServiceException.class)
public CommonResult<?> serviceExceptionHandler(ServiceException ex) {
log.info("[serviceExceptionHandler]", ex);
return CommonResult.error(ex.getCode(), ex.getMessage());
}
/**
* 处理参数校验异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public CommonResult<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
assert fieldError != null;
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", fieldError.getDefaultMessage()));
}
}
```
### 业务异常抛出
```java
// 在Service中抛出业务异常
public void validateUserExists(Long id) {
if (userMapper.selectById(id) == null) {
throw exception(USER_NOT_EXISTS);
}
}
// 错误码定义
public interface ErrorCodeConstants {
ErrorCode USER_NOT_EXISTS = new ErrorCode(1002001001, "用户不存在");
ErrorCode USER_USERNAME_EXISTS = new ErrorCode(1002001002, "用户账号已经存在");
}
```
## 接口文档规范
### Swagger 注解使用
```java
@Api(tags = "管理后台 - 用户管理") // 控制器分组
@ApiOperation("创建用户") // 接口说明
@ApiParam(value = "用户ID", required = true) // 参数说明
@ApiModel("用户信息") // 模型说明
@ApiModelProperty(value = "用户编号", example = "1") // 字段说明
```
### 接口文档示例
```yaml
# 生成的 OpenAPI 文档格式
paths:
/admin-api/system/user/create:
post:
tags:
- 管理后台 - 用户管理
summary: 创建用户
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserCreateReqVO'
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/CommonResultLong'
```
## 版本管理
### API 版本控制
```java
// 使用路径版本控制
@RequestMapping("/admin-api/v1/system/user")
// 使用请求头版本控制
@RequestMapping(value = "/admin-api/system/user", headers = "version=1.0")
// 使用参数版本控制
@RequestMapping(value = "/admin-api/system/user", params = "version=1.0")
```
### 向后兼容
- 新增字段设为可选
- 保持现有字段不变
- 废弃字段标记 @Deprecated
- 提供迁移指南
## 性能优化
### 批量操作
```java
@PostMapping("/batch-delete")
@ApiOperation("批量删除用户")
public CommonResult<Boolean> deleteUsers(@RequestBody Set<Long> ids) {
userService.deleteUsers(ids);
return success(true);
}
```
### 异步处理
```java
@PostMapping("/export")
@ApiOperation("导出用户数据")
public CommonResult<String> exportUsers(@Valid UserExportReqVO reqVO) {
// 异步处理导出任务
String taskId = userService.exportUsersAsync(reqVO);
return success(taskId);
}
```
### 缓存策略
```java
@GetMapping("/get")
@Cacheable(value = "user", key = "#id")
public CommonResult<UserRespVO> getUser(@RequestParam("id") Long id) {
UserDO user = userService.getUser(id);
return success(UserConvert.INSTANCE.convert(user));
}
```