将API调用函数返回值Unmarshal到struct的正确实现模式是什么
Go 场景下 callAPI 函数的方案选择建议
不同方案的适用场景
方案1:调整返回值为 Company 结构体
- 适用场景:
callAPI是仅针对返回 Company 结构的专用接口调用函数,没有复用对接其他接口的需求 - 优势:类型安全,编译期即可检查字段匹配问题,调用侧无需处理序列化相关逻辑,代码简洁
- 劣势:复用性差,后续需要对接其他返回结构的接口时,需要重复编写请求发送的模板代码
方案2:返回 []byte 原始JSON数据
- 适用场景:
callAPI需要作为通用工具函数对接多类接口,且调用侧需要保留原始JSON用于日志存储、问题排查等额外场景 - 优势:灵活性最高,调用侧可以根据实际业务需求自主选择反序列化的目标结构
- 劣势:每个调用侧都需要重复编写反序列化、错误处理逻辑,冗余代码多
方案3:业界通用的最优实现(推荐)
可以调整callAPI的参数,接收一个用于接收反序列化结果的指针参数,函数仅返回错误类型,签名参考:func callAPI(reqParam interface{}, result interface{}) error
- 实现逻辑:在
callAPI内部完成请求发送、响应体读取、反序列化全流程,直接将反序列化结果写入传入的result指针中 - 优势:同时兼顾复用性和易用性,既可以对接任意返回结构的接口,也不需要调用侧重复编写反序列化模板代码,HTTP状态校验、通用错误码处理等逻辑也可以统一封装在函数内部
参考代码示例:
// callAPI 通用接口调用函数定义 func callAPI(url string, method string, reqBody interface{}, result interface{}) error { // 省略请求构造、发送、HTTP状态码校验逻辑 respBody, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("read response failed: %w", err) } // 内部统一处理反序列化 if err = json.Unmarshal(respBody, result); err != nil { return fmt.Errorf("unmarshal response failed: %w", err) } return nil } // 调用侧使用示例 var company Company err := callAPI("https://your-api-domain/company/info", "GET", nil, &company) if err != nil { // 处理业务错误 }
选择建议
- 若
callAPI为专用接口调用函数,无复用需求,直接返回Company即可,实现成本最低 - 若
callAPI需要作为通用工具复用,优先选择方案3,平衡灵活性和开发效率 - 仅当调用侧有保留原始JSON的特殊需求时,再选择返回
[]byte的方案
内容的提问来源于stack exchange,提问作者chrisxfire
相关产品推荐
相关产品推荐

