RESTful设计与参数校验详解

📅 发布时间:2026/10/11 19:06:30
RESTful设计与参数校验详解
RESTful设计与参数校验详解定位第 03 篇讲透 REST 设计规范、版本管理、Bean Validation 校验体系与错误响应标准化适用版本Spring Framework 6.xJDK 17目录一、REST 设计规范二、版本管理三、参数校验四、错误响应标准化五、总结六、常见高频面试题一、REST 设计规范1.1 核心原则原则要点资源化一切皆资源用名词标识/orders/{id}不用动词避免/getOrder无状态每个请求自带鉴权与上下文服务端不存会话利于水平扩展统一接口用 HTTP 方法与状态码表达语义而非自定义动词1.2 资源命名与集合复数名词 /orders、/users 层级表达从属 /users/{id}/orders用户的订单 动作用子资源 /orders/{id}/refundPOST动作即资源 避免/getUsers、/deleteOrder、URL 里带动词1.3 状态码规范必记状态码语义200成功有响应体201创建成功常带 Location204成功、无内容如删除400请求参数错误401未认证没登录/凭证无效403已认证但无权限404资源不存在409冲突如重复创建422语义校验失败500服务端错误1.4 查询、分页、过滤过滤 /orders?statusPAIDuserId1 分页 /orders?page0size20 排序 /orders?sortcreateTime,desc二、版本管理策略做法特点URI 版本/v1/orders、/v2/orders直观、易路由最常用头版本Accept: application/vnd.api.v2json更纯但不直观参数版本?version2少用兼容性纪律呼应接口契约加字段向后兼容删字段、改类型、改语义必须升版本旧版本保留过渡期后下线。三、参数校验3.1 Bean Validation 注解publicclassUserCreateReq{NotBlank(message用户名不能为空)privateStringname;Email(message邮箱格式错误)privateStringemail;Min(value0)Max(value150)privateIntegerage;Size(max20)privateStringnickname;}3.2 触发与失败处理PostMappingUsercreate(RequestBodyValidUserCreateReqreq){...}Valid/Validated触发校验失败抛MethodArgumentNotValidException交全局异常处理转 400 字段级错误信息。3.3 进阶特性用法嵌套校验对象字段上加Valid校验内部对象的约束分组校验Validated(Create.class)注解上标分组自定义约束自定义注解 ConstraintValidator如手机号方法级校验类上 Validated校验方法参数配合 AOP四、错误响应标准化4.1 ProblemDetailRFC 7807Boot 3 内置{type:about:blank,title:Bad Request,status:400,detail:用户名不能为空,instance:/users}Boot 3 可开启spring.mvc.problemdetails.enabledtrue让默认错误走该格式。4.2 自定义统一错误体RestControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(MethodArgumentNotValidException.class)ResponseEntityApiErrorinvalid(MethodArgumentNotValidExceptione){// 提取各字段错误 → 400 结构化错误体}ExceptionHandler(BizException.class)ResponseEntityApiErrorbiz(BizExceptione){returnResponseEntity.badRequest().body(ApiError.of(e.getCode(),e.getMessage()));}}要点业务错误码 人类可读消息 字段级明细状态码与错误语义对齐细节见 04 篇异常体系。五、总结REST 规范资源化名词复数、无状态、HTTP 方法与状态码表达语义查询/分页/排序走查询参数。状态码201 创建、204 无内容、401 未认证、403 无权限、409 冲突、422 校验失败——与语义对齐而非全 200。版本管理URI 版本最常用加字段兼容、破坏性变更升版本。校验Bean Validation 注解 Valid 触发 全局异常转 400支持嵌套/分组/自定义约束。错误标准化ProblemDetailRFC 7807或自定义统一错误体业务码 可读消息 字段明细。六、常见高频面试题1. 什么是 REST核心设计原则有哪些要点REST 是以资源为中心的架构风格。原则资源化用名词标识资源如 /orders/{id}统一接口用 HTTP 方法表达操作、状态码表达结果无状态请求自带鉴权服务端不存会话利于水平扩展分层系统与按需代码可选。资源用复数名词、层级表达从属避免动词式 URL。2. HTTP 方法中哪些是幂等的为什么重要要点幂等指同一请求执行一次与多次效果相同。GET、PUT、DELETE 幂等POST、PATCH 非幂等通常。重要性幂等性决定能否安全重试——网络超时后幂等请求可放心重发非幂等重试可能重复创建/扣款。这与分布式重试纪律一致非幂等需幂等键或禁止重试。3. 常见状态码的语义401 和 403 的区别要点200 成功、201 创建成功、204 成功无内容、400 参数错误、404 资源不存在、409 冲突、500 服务端错误。401 未认证——身份凭证缺失或无效“你是谁不知道”应引导登录403 已认证但无权限“知道你是谁但不能做”。混用会导致前端无法正确处理该跳登录还是提示无权限。4. Spring 里如何做参数校验要点用 Bean ValidationJakarta Validation。入参 DTO 上标约束注解NotBlank/Email/Min/Size 等控制器方法参数上加 Valid 或 Validated 触发校验失败抛 MethodArgumentNotValidException用 RestControllerAdvice 全局捕获转成 400 字段级错误信息。支持嵌套校验字段加 Valid、分组校验、自定义约束注解。5. 如何自定义校验规则如手机号要点定义注解Phone用 Constraint 关联校验器实现 ConstraintValidatorPhone, String在 isValid 写校验逻辑正则。注解即可像内置注解一样用在字段上随 Valid 触发。适合内置注解无法覆盖的业务规则手机号、证件号、自定义业务合法性复用且集中。6. 为什么推荐统一错误响应格式要点统一错误体状态码 业务错误码 可读消息 字段明细让前端/调用方可编程地处理错误按错误码分支、展示消息而不是解析各异的堆栈或自由格式也利于网关聚合与日志关联。实现用 RestControllerAdvice 全局异常处理器把各类异常映射为统一结构Boot 3 可直接用 ProblemDetailRFC 7807标准。7. API 版本管理怎么做要点常见三种——URI 版本/v1/、/v2/最直观易路由、请求头版本Accept 带版本更纯但不直观、参数版本少用。兼容纪律加字段向后兼容删字段/改类型/改语义必须升版本旧版本保留过渡期并公告下线时间。目标是让演进不破坏存量客户端。8. 校验失败应该返回什么状态码要点入参格式/约束校验失败通常返回 400Bad Request并带字段级错误明细语义层面的失败格式对但业务不满足可用 422Unprocessable Entity。关键是响应体包含哪个字段、什么原因便于客户端修正。不要返回 500那是服务端问题也不要 200 包错误码状态码与语义应对齐。9. Valid 和 Validated 的区别要点都触发 Bean Validation。Valid 是 Jakarta 标准注解支持嵌套校验在对象字段上标注校验内部对象可用于字段/参数Validated 是 Spring 的扩展支持分组校验Validated(Group.class)用于类/方法/参数类上标注还能启用方法级校验配合 AOP。日常参数校验两者皆可需要分组或方法级校验用 Validated需要嵌套用 Valid。10. 无状态对设计有什么影响要点服务端不在内存/会话中保存客户端状态每个请求自带全部所需信息如 Token。影响① 水平扩展容易——请求可打到任意实例无需会话粘滞② 鉴权用自包含凭证JWT或集中会话存储Redis③ 需要上下文的场景显式传递请求头/参数。代价是每请求传凭证与可能的重复解析用缓存缓解。