后端开发中,请求与响应是否应使用不同的struct?
后端请求与响应结构体的设计选择
核心原则:分离优先,复用为辅
后端没有绝对的“标准做法”,但行业普遍遵循职责单一的设计思路,具体可分情况处理:
1. 字段不同时:必须分离
就像你举的登录示例,请求需要Email和Password,响应返回Email、UID及令牌类字段,两者字段差异明显时,一定要用分离的结构体:
- 规避敏感字段泄露风险:如果共用一个结构体,哪怕不填充
Password,序列化时也可能输出空值,存在安全隐患; - 逻辑边界清晰:请求结构体只负责接收前端输入,响应结构体只负责返回业务结果,后续修改其中一个时不会影响另一个(比如新增请求参数无需改动响应结构)。
请求结构体示例:
package domain type SignIn struct { Email string `json:"email"` Password string `json:"password"` }
响应结构体示例:
package domain type SignInResponse struct { Email string `json:"email"` UID string `json:"UID"` AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` }
2. 字段完全相同时:可复用但不强制
如果接口的请求与响应字段完全一致(比如简单查询接口,请求传ID、响应返回对应完整实体),可以考虑复用同一个结构体,但要满足两个前提:
- 后续业务大概率不会出现字段差异:若未来可能给请求或响应新增不同字段,建议一开始就分开,避免后期重构成本;
- 无敏感字段风险:比如响应不会泄露请求中的敏感数据(若提交接口的请求包含敏感信息,但响应仅返回成功状态,就不能复用)。
3. 部分字段重叠时:优先分离,用嵌入结构体减少重复
如果请求和响应有部分字段相同(比如用户信息接口,请求传UID,响应返回UID、Name、Email等),不要直接共用结构体,可通过Go的结构体嵌入减少重复代码:
先定义基础用户结构体:
package domain type UserBase struct { UID string `json:"uid"` Email string `json:"email"` }
再分别嵌入到请求和响应结构体中:
// 请求结构体 type GetUserRequest struct { UserBase } // 响应结构体 type GetUserResponse struct { UserBase Name string `json:"name"` Age int `json:"age"` }
既保证了职责分离,又避免了重复定义相同字段。
不推荐“用同一个结构体仅填充所需字段”的原因
这种做法看似省事,但存在明显问题:
- 可读性差:其他开发者难以快速区分哪些字段用于请求、哪些用于响应,维护成本高;
- 序列化风险:多数JSON库会序列化结构体所有字段,哪怕值为空,可能返回多余空字段给前端,或不小心泄露敏感字段;
- 扩展性差:后续业务变化时,修改结构体极易影响请求或响应逻辑,引发bug。
内容的提问来源于stack exchange,提问作者EmanuelLamba
相关产品推荐
相关产品推荐

