# 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 createUser(@Valid @RequestBody UserCreateReqVO reqVO) { return success(userService.createUser(reqVO)); } @PutMapping("/update") @ApiOperation("修改用户") @PreAuthorize("@ss.hasPermission('system:user:update')") @OperateLog(type = UPDATE) public CommonResult 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 deleteUser(@RequestParam("id") Long id) { userService.deleteUser(id); return success(true); } @GetMapping("/get") @ApiOperation("获得用户") @PreAuthorize("@ss.hasPermission('system:user:query')") public CommonResult 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> getUserPage(@Valid UserPageReqVO reqVO) { PageResult pageResult = userService.getUserPage(reqVO); return success(UserConvert.INSTANCE.convertPage(pageResult)); } @GetMapping("/list") @ApiOperation("获得用户列表") @PreAuthorize("@ss.hasPermission('system:user:query')") public CommonResult> getUserList(@Valid UserListReqVO reqVO) { List 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 postIds; @ApiModelProperty(value = "用户角色编号数组", example = "1") private Set 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 roleIds; /** * 所属岗位 */ private Set 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 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 deleteUsers(@RequestBody Set ids) { userService.deleteUsers(ids); return success(true); } ``` ### 异步处理 ```java @PostMapping("/export") @ApiOperation("导出用户数据") public CommonResult exportUsers(@Valid UserExportReqVO reqVO) { // 异步处理导出任务 String taskId = userService.exportUsersAsync(reqVO); return success(taskId); } ``` ### 缓存策略 ```java @GetMapping("/get") @Cacheable(value = "user", key = "#id") public CommonResult getUser(@RequestParam("id") Long id) { UserDO user = userService.getUser(id); return success(UserConvert.INSTANCE.convert(user)); } ```