最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
深入解析SpringBoot中微服务API三层分级设计
时间:2026-08-10 16:41:51 编辑:袖梨 来源:一聚教程网
深入解析SpringBoot中微服务API三层分级设计的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
一、什么是 API 分层
API 分层是微服务架构中对外暴露接口的一种组织策略。根据调用方是谁、安全要求有多高,将同一个服务的接口划分为不同层级,每个层级有独立的 URL 前缀、认证方式和职责边界。

核心思想:同一份业务逻辑,对不同调用方暴露不同的接口视图。
二、三层划分
2.1 Page API — 面向前端
| 项目 | 说明 |
|---|---|
| URL 前缀 | /api/page/{domain}/{action} |
| 调用方 | 前端页面(浏览器、APP) |
| 认证方式 | JWT Token(用户登录后获取) |
| 特点 | 返回完整数据、支持分页、依赖当前登录用户上下文 |
适用场景: 用户在界面上点击按钮触发的操作。比如用户提交审核、查询列表。
@Tag(name = "订单管理", description = "订单管理页面接口")@RestController@RequestMapping("/api/page/order")public interface OrderPageApi { @Operation(summary = "查询订单列表", security = {@SecurityRequirement(name = "bearer-jwt")}) @PostMapping("/list-orders") RestControllerResult<PageInfo<OrderListResultDto>> listOrders( @RequestBody OrderListParamsDto paramsDto); @Operation(summary = "取消订单") @PostMapping("/cancel-order") RestControllerResult<Boolean> cancelOrder( @RequestBody CancelOrderParamsDto paramsDto);}Controller 实现中通常会从 JWT 中获取当前用户信息:
@RestControllerpublic class OrderPageApiController implements OrderPageApi { @Override public RestControllerResult<PageInfo<OrderListResultDto>> listOrders( OrderListParamsDto paramsDto) { // 从JWT中获取当前登录用户的memberId if (paramsDto.getMemberId() == null) { paramsDto.setMemberId(JwtTokenUtil.getMemberId().intValue()); } return RestControllerResult.success(orderService.listOrders(paramsDto)); }}2.2 Inner API — 微服务间调用
| 项目 | 说明 |
|---|---|
| URL 前缀 | /api/inner/{domain}/{action} |
| 调用方 | 其他内部微服务(通过 Feign/HTTP) |
| 认证方式 | IP 白名单 / 服务间 Token / 网关转发 |
| 特点 | 参数完整(调用方直接传 memberId),不依赖用户登录上下文 |
适用场景: 服务 A 需要调用服务 B 的能力。
@Tag(name = "订单内部接口", description = "供其他微服务调用")@RestController@RequestMapping("/api/inner/order")public interface OrderInnerApi { @Operation(summary = "根据订单号查询订单详情") @GetMapping("/get-order-by-code") RestControllerResult<OrderDetailDto> getOrderByCode( @RequestParam("orderCode") String orderCode); @Operation(summary = "生成退货单") @PostMapping("/create-return-order") RestControllerResult<ReturnOrderResultDto> createReturnOrder( @RequestBody CreateReturnOrderParamsDto paramsDto);}其他服务通过 Feign 客户端调用:
@FeignClient( value = "${service-name.order}/api", fallbackFactory = OrderFeignFallbackFactory.class)public interface OrderFeign { @PostMapping("/inner/order/create-return-order") RestControllerResult<ReturnOrderResultDto> createReturnOrder( @RequestBody CreateReturnOrderParamsDto paramsDto);}调用方代码:
@Servicepublic class StockServiceImpl { @Resource private OrderFeign orderFeign; public void doSomething() { CreateReturnOrderParamsDto params = new CreateReturnOrderParamsDto(); params.setMemberId(226887); params.setOrderCode("xxx.xxx.000001"); RestControllerResult<ReturnOrderResultDto> result = orderFeign.createReturnOrder(params); if (!result.getSuccess()) { throw new RuntimeException("生成退货单失败: " + result.getErrorMsg()); } }}2.3 Composite API — 跨服务聚合
| 项目 | 说明 |
|---|---|
| URL 前缀 | /api/composite/{domain}/{action} |
| 调用方 | 外部合作伙伴系统 / 需要聚合多服务数据的场景 |
| 认证方式 | JWT 或 API Key |
| 特点 | 单个接口内部可能调用多个服务,做数据组装和聚合 |
适用场景: 外部系统需要一个接口获取多维度的聚合数据。比如需要同时查库存异动表、商品信息、存性信息、订单类型等。
@Tag(name = "数据聚合服务", description = "跨服务聚合查询")@RestController@RequestMapping("/api/composite/stock/data-center")public interface StockDataCompositeApi { @Operation(summary = "查询出入库汇总信息") @PostMapping("/get-stock-transaction-summary") RestControllerResult<StockTransactionSummaryDto> getStockTransactionSummary( @RequestBody StockTransactionSummaryParamsDto paramsDto);}Controller 实现中会调用多个服务/数据源聚合:
@RestControllerpublic class StockDataCompositeApiController implements StockDataCompositeApi { @Resource private StockMapper stockMapper; // 本地查库存数据 @Resource private OrderFeign orderFeign; // 远程查订单数据 @Resource private GoodsFeign goodsFeign; // 远程查商品数据 @Override public RestControllerResult<StockTransactionSummaryDto> getStockTransactionSummary( StockTransactionSummaryParamsDto paramsDto) { // 1. 查本地库存异动 List<StockTransactionDto> transactions = stockMapper.selectTransactions(paramsDto); // 2. 远程调用订单服务补充订单类型名称 List<String> orderCodes = transactions.stream() .map(StockTransactionDto::getOrderCode).collect(Collectors.toList()); Map<String, String> orderTypeMap = orderFeign.getOrderTypes(orderCodes); // 3. 远程调用商品服务补充商品信息 List<Integer> skuIds = transactions.stream() .map(StockTransactionDto::getItemSkuId).collect(Collectors.toList()); Map<Integer, ItemInfoDto> itemMap = goodsFeign.getItemInfoBatch(skuIds); // 4. 组装聚合结果 transactions.forEach(t -> { t.setOrderTypeName(orderTypeMap.get(t.getOrderCode())); ItemInfoDto item = itemMap.get(t.getItemSkuId()); if (item != null) { t.setItemName(item.getItemName()); t.setProductCode(item.getProductCode()); } }); return RestControllerResult.success(new StockTransactionSummaryDto(transactions)); }}三、三层对比
┌─────────────────────────────────────────────────────────┐
│ 网关 (Gateway) │
├──────────┬──────────────────┬───────────────────────────┤
│ │ │ │
│ 前端/APP │ 其他微服务 │ 外部合作伙伴系统 │
│ │ │ │
├──────────┼──────────────────┼───────────────────────────┤
│ ↓ ↓ ↓
│ /api/page/* /api/inner/* /api/composite/*
│ │ │ │
│ 需要登录JWT IP白名单/服务Token JWT/API Key
│ │ │ │
│ 依赖用户上下文 参数完整自包含 聚合多数据源
│ │ │ │
├──────────┴──────────────────┴───────────────────────────┤
│ Service 业务逻辑层 │
│ (三层共享同一个 Service) │
└─────────────────────────────────────────────────────────┘
关键点:三层 API 只是入口不同,最终都调用同一个 Service 层的业务逻辑。
四、URL 路径规范
格式:/api/{层级}/{领域}/{资源或模块}/{动作}
/api/page/stock/xx-xx/audit-reject-apply
│ │ │ │
│ │ │ └── 动作:审核拒收申请
│ │ └── 模块:xxx
│ └── 领域:库存
└── 层级:页面接口
/api/inner/stock/xx-xx/receive-order-center-reject-audit-result
│ │ │ │
│ │ │ └── 动作:接收xx拒收审核结果
│ │ └── 模块:xx
│ └── 领域:库存
└── 层级:内部接口
/api/composite/stock/xxx/get-union-stock-transaction-pager
│ │ │ │
│ │ │ └── 动作:查询出入库信息
│ │ └── 模块:xxx
│ └── 领域:库存
└── 层级:复合接口
五、接口定义与实现分离模式
// 第一层:接口定义(放在 api 包下)// 作用:定义契约,可以被其他服务引用@RestController@RequestMapping("/api/inner/order")public interface OrderInnerApi { @PostMapping("/get-order-detail") RestControllerResult<OrderDetailDto> getOrderDetail(@RequestBody OrderQueryDto dto);}// 第二层:Controller 实现(放在 controller 包下)// 作用:参数校验 + 调用 Service@RestControllerpublic class OrderInnerApiController implements OrderInnerApi { @Resource private OrderService orderService; @Override public RestControllerResult<OrderDetailDto> getOrderDetail(OrderQueryDto dto) { if (dto.getOrderCode() == null) { throw new JshCheckException("订单号不能为空"); } return RestControllerResult.success(orderService.getOrderDetail(dto)); }}// 第三层:Service 接口 + 实现public interface OrderService { OrderDetailDto getOrderDetail(OrderQueryDto dto);}@Servicepublic class OrderServiceImpl implements OrderService { @Override public OrderDetailDto getOrderDetail(OrderQueryDto dto) { // 真正的业务逻辑 }}六、统一返回包装
所有层级的接口都用 RestControllerResult<T> 包装返回值:
public class RestControllerResult<T> { private Boolean success; // 是否成功 private Integer code; // 状态码(0=正常) private String errCode; // 错误编码 private String errorMsg; // 错误信息 private T data; // 业务数据 private List<String> infoMsgs; private List<String> warningMsgs;}调用方统一处理:
RestControllerResult<OrderDetailDto> result = orderFeign.getOrderDetail(dto);if (!result.getSuccess()) { // 处理失败 log.error("调用失败: {}", result.getErrorMsg()); throw new RuntimeException(result.getErrorMsg());}OrderDetailDto data = result.getData();七、安全机制对比
Page API — JWT 认证
前端登录 -> 获取 access_token -> 每次请求 Header 携带 Authorization: Bearer <token>
↓
服务端 RSA 公钥验签 -> 解析出 userId/memberId
Inner API — 网关转发 + IP 白名单
服务A -> 通过注册中心/网关路由到服务B -> 网关层验证来源IP在白名单中
内部服务间不需要用户登录态,参数中直接传 memberId。
Composite API — 按场景选择
可以是 JWT,也可以是 API Key(如开放平台场景)。
八、同一业务不同层级暴露不同接口的例子
以"审核拒收申请"为例,三层可以暴露不同的入口:
// Page API:前端用户手动审核(从JWT获取审核人信息)@PostMapping("/api/page/stock/xxx/audit-reject-apply")RestControllerResult<Boolean> auditRejectApply(@RequestBody AuditRejectApplyParamsDto dto);// Inner API:xx系统审核(入参直接传审核信息,不依赖登录态)@PostMapping("/api/inner/stock/xxx/audit-reject-apply-by-xx")RestControllerResult<Boolean> auditRejectApplyByXx(@RequestBody AuditRejectApplyByLmParamsDto dto);两个接口最终都调用同一个 Service 方法。
区别在于:
- Page 版本从 JWT 中取审核人、做前端相关的校验
- Inner 版本从入参中取审核信息、做系统间交互的校验
九、何时选择哪个层级
| 场景 | 选择 | 理由 |
|---|---|---|
| 用户在页面点击按钮 | Page | 需要登录态,依赖当前用户 |
| A服务需要查B服务 | Inner | 微服务间调用,不需要用户登录 |
| 定时任务触发 | Page 或 Inner | 取决于是否需要用户上下文 |
| 外部系统查询聚合数据 | Composite | 需要组装多数据源,对外提供 |
| 外部系统回传结果 | Inner | 系统间调用,参数自包含 |
| 开放平台对外暴露 | Composite | API Key 认证,聚合返回 |
相关文章
- 外研U学app如何加入班级 08-10
- jm网页版进入-jm网页直接进入 08-10
- mc我的世界如何免费秒玩 08-10
- 126邮箱登录入口网页版手机-126邮箱手机网页版访问地址 08-10
- 原神国际服通行证入口在哪-国际服通行证入口地址分享 08-10
- 王者荣耀世界怎么拍照 拍照系统玩法技巧详解 08-10