微服务下 DTO 设计核心原则

文章目录


前言

微服务下 DTO 设计核心原则:

对外稳定,对内隔离,禁止直接复用数据库对象。


一、微服务调用链

text 复制代码
order-service
   ↓ Feign / RPC
user-service
stock-service
coupon-service
pay-service

服务之间传的对象一般就是:

text 复制代码
RequestDTO / ResponseDTO

二、推荐命名

请求对象

java 复制代码
CreateOrderRequest
DeductStockRequest
UserQueryRequest

或者:

java 复制代码
CreateOrderDTO
DeductStockDTO

我更推荐微服务接口用:

text 复制代码
XXXRequest / XXXResponse

因为语义更清楚。


三、Feign 接口示例

stock-api 模块

java 复制代码
@FeignClient(name = "stock-service")
public interface StockClient {

    @PostMapping("/api/stock/deduct")
    StockDeductResponse deduct(@RequestBody StockDeductRequest request);
}

请求 DTO

java 复制代码
public class StockDeductRequest {
    private Long skuId;
    private Integer count;
    private String requestId;
}

返回 DTO

java 复制代码
public class StockDeductResponse {
    private Boolean success;
    private String code;
    private String message;
}

四、微服务 DTO 不要放在哪?

不要放在:

text 复制代码
order-service 内部 domain 包
stock-service 内部 entity 包

否则其他服务依赖会很乱。

推荐建独立 API 包:

text 复制代码
stock-api
  ├── client
  │   └── StockClient.java
  ├── dto
  │   ├── StockDeductRequest.java
  │   └── StockDeductResponse.java

然后:

text 复制代码
order-service 依赖 stock-api
stock-service 实现 stock-api

五、不要直接暴露 Entity / DO

错误示例:

java 复制代码
@PostMapping("/user/get")
UserDO getUser(@RequestBody UserDO user);

问题:

text 复制代码
数据库结构泄露
字段一改,调用方全炸
可能暴露敏感字段
服务边界不清晰

正确:

java 复制代码
UserQueryRequest
UserResponse

六、DTO 要分"入参"和"出参"

不要一个对象到处复用。

错误:

java 复制代码
UserDTO 同时用于创建、修改、查询、返回

正确:

java 复制代码
UserCreateRequest
UserUpdateRequest
UserQueryRequest
UserResponse

因为不同场景字段不一样:

text 复制代码
创建需要 password
返回不能有 password
修改可能只传 nickname
查询可能只传 userId/mobile

七、统一返回结构

微服务之间建议统一响应:

java 复制代码
public class RpcResult<T> {
    private boolean success;
    private String code;
    private String message;
    private T data;
}

例如:

java 复制代码
RpcResult<UserResponse> getUser(UserQueryRequest request);

八、版本兼容很重要

DTO 一旦被其他服务依赖,就不能随便改。

推荐规则:

text 复制代码
新增字段:可以
删除字段:谨慎
改字段类型:禁止
改字段含义:禁止
字段重命名:基本等于破坏兼容

如果必须大改:

text 复制代码
/api/v2/user/query
UserQueryV2Request
UserV2Response

九、订单服务调用用户服务示例

java 复制代码
@Service
public class OrderService {

    private final UserClient userClient;

    public OrderService(UserClient userClient) {
        this.userClient = userClient;
    }

    public void createOrder(Long userId) {
        RpcResult<UserResponse> result =
                userClient.getUser(new UserQueryRequest(userId));

        if (!result.isSuccess()) {
            throw new RuntimeException("查询用户失败");
        }

        UserResponse user = result.getData();

        // 创建订单逻辑
    }
}

十、推荐目录结构

text 复制代码
user-api
  ├── client
  │   └── UserClient.java
  ├── request
  │   └── UserQueryRequest.java
  ├── response
  │   └── UserResponse.java
  └── result
      └── RpcResult.java

user-service
  ├── controller
  ├── service
  ├── domain
  ├── mapper
  └── converter

order-service
  ├── controller
  ├── service
  └── client

一句话总结

微服务 DTO 是服务契约,不是数据库对象;Feign/RPC 接口要用独立 API 模块维护 Request/Response,并注意版本兼容。

相关推荐
another heaven36 分钟前
【C/C++ C++ 面向对象架构的五大特点与能力场景:封装、继承、多态、抽象与 RAII(含实战案例)】
c语言·c++·架构
微订校园外卖平台1 小时前
乡镇外卖跑腿代办系统怎么选:四端架构与实施核对
架构·外卖系统·本地生活·微订
这个DBA有点耶1 小时前
测试全绿,上线三周数据没入账——那个95%的兼容度报告,漏掉的是边界
数据库·mysql·架构
时间售卖铺2 小时前
MySQL 日志管理
运维·数据库·mysql·云原生
X54先生(人文科技)3 小时前
ELR-SELLM_硅基伙伴通过对话碰撞个性涌现的推理架构_v10
人工智能·深度学习·架构·零知识证明
老郭a3 小时前
流量一涨 Pod 扩不出来?K8s HPA 弹性伸缩配置避坑指南
云原生
鱼儿也有烦恼3 小时前
客户端应用架构模式
android·架构
愤怒火龙果3 小时前
AI 渗透测试智能体架构综述:从单兵到蜂群的演进图谱
人工智能·网络安全·架构
Oiiouui3 小时前
Godot-GridGame架构逻辑层与实体/物品层篇
架构·游戏引擎·godot
涛声依旧-底层原理研究所4 小时前
Agent 沙箱实现原理:拆解 DeepSeek Harness 的三层沙箱架构与三平台后端
人工智能·架构