今天学习了为什么要在一个小项目中引入另一个项目的请求/响应层 加深了我的个人理解

因为这是微服务架构中 “管理后台(admin)与核心服务(project)解耦” 的典型设计
接下来我将从五点来对本次学习进行一个学习总结
一、为什么复制 req/resp 到 admin 项目?(核心:隔离与兼容)
场景:
project是短链接核心服务(负责生成、存储短链接)。admin是管理后台(负责分页查询、统计等管理功能)。
复制原因:
避免直接依赖核心服务代码
如果 admin 直接引用 project 的
ShortLinkPageReqDTO,会导致:
核心服务代码变更时,admin 必须同步修改(耦合严重)。
部署时 admin 依赖 project 的 jar 包,违背微服务 “独立部署” 原则。
复制 DTO 后,admin 只关心 “接口契约”(字段名、类型),不关心核心服务的实现细节。
数据格式对齐
管理后台的查询参数(如
gid、分页参数)必须与核心服务的接口输入 / 输出完全一致,否则远程调用会失败。复制 DTO 是最简单的 “契约对齐” 方式(比用 Swagger 自动生成更直接)。
二、为什么在 admin 中创建 ShortLinkRemoteService?(核心:远程调用封装)
代码作用:
java
public interface ShortLinkRemoteService {
default Result<IPage<ShortLinkPageRespDTO>> pageShortLink(ShortLinkPageReqDTO requestParam) {
// 1. 将参数转为 Map(HTTP 请求参数)
// 2. 调用核心服务的 HTTP 接口
// 3. 解析返回的 JSON 为 Result 对象
}
}这是 “远程服务代理”,作用是:
隐藏远程调用细节
管理后台的业务代码(如 Controller)无需关心 “核心服务是 HTTP 还是 RPC 调用”,只需调用
ShortLinkRemoteService的方法。未来如果核心服务从 HTTP 改为 Dubbo 或 gRPC,只需修改
default方法的实现,不影响上层调用。
适配管理后台的业务逻辑
核心服务返回的
IPage可能包含敏感字段(如数据库主键),ShortLinkPageRespDTO可以裁剪为管理后台需要的字段(如只保留短链接、创建时间)。
三、为什么没有实现类?(核心:Java 接口的 default 方法特性)
常规写法 vs 你的代码:
你的代码选择 default 的原因:
轻量级远程调用:管理后台只需要简单的分页查询,直接用 Hutool 的
HttpUtil调用,避免创建@Service类和 Spring 配置。临时过渡方案:如果未来需要添加重试、熔断等功能,可以再创建实现类覆盖
default方法:java
@Service
public class ShortLinkRemoteServiceImpl implements ShortLinkRemoteService {
@Override
public Result<IPage<ShortLinkPageRespDTO>> pageShortLink(ShortLinkPageReqDTO requestParam) {
// 新增重试逻辑 + 原 default 逻辑
}
}四、为什么在 admin 中创建 Controller?(核心:分层职责)
管理后台的 ShortLinkController 职责:
接收前端请求:解析分页参数(
current、size)和业务参数(gid)。调用远程服务:通过
ShortLinkRemoteService发起核心服务的查询。返回响应:将远程结果转换为前端需要的格式(如去除技术字段,保留业务字段)。
不直接在 Controller 写 HTTP 调用的原因(对比代码):
五、总结:这套代码的设计思想
1. 微服务解耦:
admin 与 project 是独立服务,通过 HTTP 接口通信,复制 DTO 是 “接口契约” 的显式声明。
2. 分层瘦身:
管理后台不需要完整的三层(Service+DAO),因为不直接操作数据库,只需要 “Controller + 远程服务代理”。
default方法是 “够用即可” 的设计,避免为简单功能创建冗余类。
3. 演进预留:
现在用 HTTP 直连,未来可以无缝切换为 Feign/RestTemplate 等更优雅的远程调用方案,只需修改
ShortLinkRemoteService。