Spring Boot RESTful API 设计指南:查询接口规范与最佳实践

引言

在 Spring Boot 开发中,查询接口的设计直接影响着系统的可用性、可维护性和性能。本文将深入探讨如何规范设计查询接口,包括 GET/POST 的选择、参数定义、校验规则等,并提供可落地的代码示例。

一、GET 与 POST 的选择标准

1.1 何时使用 GET 请求

GET 请求是幂等的,适合用于不修改服务器状态的查询操作:

// 商品列表查询示例
@GetMapping("/products")
public ResponseEntity<Page<Product>> queryProducts(@RequestParam(required = false) String name,@RequestParam(required = false) String category,@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size) {// 分页查询逻辑
}

优势

  • 可被缓存
  • 参数可见,便于调试
  • 支持浏览器直接访问

限制

  • URL 长度有限(约 2048 字符)
  • 参数只能简单键值对

1.2 何时使用 POST 请求

当查询条件复杂时,POST 更合适:

// 复杂商品搜索示例
@PostMapping("/products/search")
public ResponseEntity<Page<Product>> searchProducts(@RequestBody ProductSearchDTO searchDTO) {// 复杂查询逻辑
}// 搜索DTO定义
@Data
public class ProductSearchDTO {private String keyword;private List<String> categories;private PriceRange priceRange;private SortCondition sort;@Datapublic static class PriceRange {private BigDecimal min;private BigDecimal max;}
}

适用场景

  • 参数包含嵌套对象
  • 需要传递数组/集合
  • 查询条件超过 10 个字段
  • 涉及敏感数据(如身份证号查询)

二、参数设计规范

2.1 基础查询参数

推荐格式

@GetMapping("/orders")
public Page<Order> queryOrders(@RequestParam @DateTimeFormat(iso = ISO.DATE) LocalDate startDate,@RequestParam @DateTimeFormat(iso = ISO.DATE) LocalDate endDate,@RequestParam(defaultValue = "0") @Min(0) int page,@RequestParam(defaultValue = "20") @Max(100) int size) {// 查询逻辑
}

规范要点

  1. 时间参数明确格式(推荐 ISO 8601)
  2. 分页参数统一命名(page/size)
  3. 添加基础校验注解

2.2 复杂查询参数

标准DTO示例

@Data
public class AdvancedSearchDTO {@NotBlankprivate String queryType; // 搜索类型:精确/模糊@Size(max = 10)private List<@Pattern(regexp = "^[A-Za-z0-9]+$") String> codes;@Validprivate TimeRange createTime;@Datapublic static class TimeRange {@PastOrPresentprivate LocalDateTime start;@FutureOrPresentprivate LocalDateTime end;}
}

Controller使用

@PostMapping("/data/advanced-search")
public SearchResult advancedSearch(@Valid @RequestBody AdvancedSearchDTO dto) {// 参数自动校验
}

三、高级设计模式

3.1 动态查询实现

方案一:QueryDSL 动态查询

@GetMapping("/dynamic")
public List<User> dynamicQuery(@RequestParam(required = false) String name,@RequestParam(required = false) Integer age) {BooleanBuilder builder = new BooleanBuilder();if (name != null) {builder.and(user.name.contains(name));}if (age != null) {builder.and(user.age.eq(age));}return queryFactory.selectFrom(user).where(builder).fetch();
}

方案二:Specification 动态查询

@PostMapping("/spec-search")
public Page<User> specSearch(@RequestBody UserSpecification spec,Pageable pageable) {return userRepository.findAll(spec, pageable);
}

3.2 全局参数处理

统一分页参数处理

@ControllerAdvice
public class PaginationAdvice implements WebMvcConfigurer {@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(new PageableHandlerMethodArgumentResolver() {@Overridepublic Pageable resolveArgument(...) {Pageable pageable = super.resolveArgument(...);return PageRequest.of(pageable.getPageNumber(),Math.min(pageable.getPageSize(), 100),pageable.getSort());}});}
}

四、安全与性能优化

4.1 安全规范

  1. 敏感参数处理

    @PostMapping("/secure-search")
    public ResponseEntity<?> secureSearch(@Encrypted @RequestBody SensitiveSearchDTO dto) {// 自动解密处理
    }
    
  2. SQL 注入防护

    • 使用 JPA/Hibernate 参数绑定
    • 禁止字符串拼接 SQL

4.2 性能优化

  1. 分页最佳实践

    @GetMapping("/optimized")
    public Slice<Data> optimizedQuery(Pageable pageable,@RequestParam String filter) {return repository.findByFilter(filter, PageRequest.of(pageable.getPageNumber(),Math.min(pageable.getPageSize(), 50)));
    }
    
  2. 响应压缩

    # application.properties
    server.compression.enabled=true
    server.compression.mime-types=application/json
    

五、文档化与测试

5.1 Swagger 集成

@Operation(summary = "用户复杂查询")
@PostMapping("/users/advanced-search")
public Page<User> advancedUserSearch(@Parameter(description = "查询条件", required = true)@RequestBody UserSearchDTO dto,@Parameter(description = "分页参数")Pageable pageable) {// 实现逻辑
}

5.2 测试用例

MockMVC 测试示例

@Test
void testQueryWithParams() throws Exception {mockMvc.perform(get("/api/products").param("category", "electronics").param("page", "0").param("size", "10")).andExpect(status().isOk()).andExpect(jsonPath("$.content").isArray());
}

结语

良好的查询接口设计需要平衡以下因素:

  1. 语义明确:准确表达接口用途
  2. 参数规范:统一命名和结构
  3. 安全可靠:防止注入和越权
  4. 性能高效:合理分页和缓存
  5. 易于维护:完善的文档和测试

建议团队制定统一的《接口设计规范》,并使用 Swagger 等工具维护接口文档。实际开发中应根据业务场景灵活选择技术方案,避免教条主义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88740.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88740.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/88740.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow萌新题集

记录一下前半部分是能自己写出来的&#xff0c;后半部分是需要提示的&#xff0c;感觉自己归来两年仍是萌新 misc部分 知识点 base家族密文特征 Base16 (Hex) 字符集&#xff1a;0-9, A-F&#xff08;不区分大小写&#xff09;。特征&#xff1a; 长度是 2 的倍数&#xff…

2025年语言处理、大数据与人机交互国际会议(DHCI 2025)

&#x1f310;&#x1f916;&#x1f9e0; 语言处理、大数据与人机交互&#xff1a;探索智能未来 —— DHCI 2025国际会议2025年语言处理、大数据与人机交互国际会议&#xff08;DHCI 2025&#xff09; 将于2025年在中国重庆市召开。这次盛会将汇聚全球顶尖专家、学者及行业领袖…

RIP实验以及核心原理

RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种内部网关协议&#xff0c;基于距离矢量算法&#xff0c;用于在自治系统内交换路由信息。RIP 核心原理距离矢量算法&#xff1a;RIP 使用跳数作为路径选择的唯一度量标准。每经过一个路由…

基于大数据的电力系统故障诊断技术研究

摘要本文提出了一种创新性的基于大数据技术的电力系统故障诊断方法&#xff0c;该方法通过整合先进的机器学习算法和交互式可视化技术&#xff0c;实现了对电力系统各类故障的智能化识别与深度分析。该系统采用随机森林算法作为核心分类器&#xff0c;构建了高精度的故障分类模…

MySQL 分区功能应用专门实现全方位详解与示例

MySQL 分区功能允许将表的数据分散存储在不同的物理分区中,同时保持逻辑上的单一表结构。下面我将从基础概念到高级应用,全面讲解 MySQL 分区实现。 一、分区核心作用 1. 性能提升 分区剪枝(Partition Pruning):查询时自动跳过不相关的分区,减少数据扫描量 并行处理:不…

汽车功能安全-嵌入式软件测试(软件合格性测试)【目的、验证输入、集成验证要求】11

文章目录1 嵌入式软件测试&#xff08;Testing of the embedded Software&#xff09;2 测试输入3 验证要求和建议3.1 测试环境3.2 测试方法3.2.1 基于需求的测试3.2.2 故障注入测试3.2.3 两种方法的区别与联系总结3.3 测试用例导出方法4 嵌入式软件的测试结果评价5 测试输出物…

【webrtc】gcc当前可用码率1:怎么决策的

【webrtc】当前最大码率是怎么决策的1 看日志,跟踪代码最大码率 是probe的上限 默认值很大 外部设置的较小,调用堆栈 无限大作为默认值 默认是无限大,所以使用预设值 【webrtc】码率设定中的 int64_t 的无限大

UE5 C++计时器

UE5 C计时器 计时器一&#xff1a; .h文件 FTimerHandle TimerHandle_BetweenShot;//定义时间句柄 void StartFire();void EndFire();.cpp文件 #include “TimerManager.h” void ASpaceShip::StartFire() {GetWorldTimerManager().SetTimer(TimerHandle_BetweenShot, this, &a…

【hivesql 已知维度父子关系加工层级表】

这里写自定义目录标题1. 维度表示例1.1清单表1.2层级表2.从清单表加工层级表2.1 注意点2.2 加工方式&#xff08;join&#xff09;2.3 使用函数3.清单表字段加工3.1通过上级编码信息加工级别信息3.2 通过级别信息&#xff0c;加工上级编码信息4.创建维度表的一般注意点1. 维度表…

Ubuntu重装系统后ssh连接不上(遇到 ​​“Unit ssh.service not found“​​ 错误)

重装系统时不知道为什么SSH 服务未安装&#xff0c;以下是解决方案&#xff1a;先检查ssh服务安装没安装 sudo systemctl status ssh # Ubuntu/Debian如果 systemctl 找不到服务&#xff0c;可能是 SSH 未安装&#xff1a;sudo apt update sudo apt install openssh-serve…

2025社交电商新风口:推客小程序的商业逻辑与技术实现

一、推客小程序市场前景与商业价值在当今社交电商蓬勃发展的时代&#xff0c;推客小程序已成为连接商家与消费者的重要桥梁。推客模式结合了社交传播与电商变现的双重优势&#xff0c;通过用户自发分享带来裂变式增长&#xff0c;为商家创造了全新的营销渠道。推客小程序的核心…

Go 单元测试进阶:AI 加持下的高效实践与避坑指南

单元测试的必要性与基础单元测试不仅是保障代码质量的手段&#xff0c;也是优秀的设计工具和文档形式&#xff0c;对软件开发具有重要意义。另一种形式的文档&#xff1a;好的单元测试是一种活文档&#xff0c;能清晰展示代码单元的预期用途和行为&#xff0c;有时比注释更有用…

VScode SSH远程连接Ubuntu(通过SSH密钥对的方式)

我们都知道在VScode上通过SSH插件的方式可以远程连接到虚拟机的Ubuntu系统&#xff0c;这样开发者就可以在Windows下的Vscode编译器下直接远程连接Ubuntu&#xff0c;这种方式是 “用 Windows 的便捷性操作 Linux 的专业性”—— 既保留了Windows系统的易用性和VS Code的强大功…

学术绘图(各种神经网络)

23种神经网络设计&可视化工具汇总 下面做简要罗列&#xff0c;具体请看相关链接 1.draw_convnet Github: https://github.com/gwding/draw_convnet​ star 数量&#xff1a;1.7k​ 这个工具最后一次更新是2018年的时候&#xff0c;一个Python脚本来绘制卷积神经网络的工…

Redis的高可用性与集群架构

Redis的高可用性与集群架构 引言&#xff1a;解释高可用性的重要性及Redis如何实现主从复制&#xff08;Replication&#xff09; 原理&#xff1a;异步复制&#xff0c;主从数据同步配置方法优缺点分析 哨兵模式&#xff08;Sentinel&#xff09; 功能&#xff1a;监控、通知、…

TCP的连接

TCP 三次握手过程是怎样的&#xff1f;TCP 是面向连接的协议&#xff0c;所以使用 TCP 前必须先建立连接&#xff0c;而建立连接是通过三次握手来进行的。三次握手的过程如下图&#xff1a;一开始&#xff0c;客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口&…

Excel的学习

一、熟悉界面 1.功能区 点击“视图”,点击冻结窗格,选择目标行 2.表格区 3.自定义功能区 在上面的空白编辑栏处,右键选择自定义功能区 4.数据输入规范 (1)格式不统一(日期格式不规范,姓名乱加空格,乱合并单元格) 姓名对齐:右键选择编辑单元格格式,选择对齐,…

论文阅读:HybridTrack: A Hybrid Approach for Robust Multi-Object Tracking

论文地址:2501.01275v2 代码地址:GitHub - leandro-svg/HybridTrack: [RA-L25/ICRA26] HybridTrack: A Hybrid Approach for Robust Multi-Object Tracking 前言 多目标跟踪旨在在帧间检测和关联所有所需的目标。大多数方法通过明确或隐式地利用强大的线索(即空间和外观信…

EtherCAT开源主站 SOEM 2.0 最新源码在嵌入式 Linux 下的移植与编译

EtherCAT 作为工业自动化领域的主流现场总线协议&#xff0c;因其高实时性和高带宽被广泛应用。而 SOEM&#xff08;Simple Open EtherCAT Master&#xff09;则是开源社区中最受欢迎的 EtherCAT 主站协议栈之一。本文将以 SOEM 2.0 最新源码为例&#xff0c;详细介绍其在嵌入式…