>我有多个 API 在高级响应中遵循类似的结构。它总是以这种形式返回答案:
{"data": {"feed":[{...}]}, "success": true}
但是,源中的结构会有所不同,具体取决于具体的 API。
我现在想构建一个抽象函数来处理各种 API。我有以下对象:
type SourceDTO struct { // top level object
Success bool `json:"success"`
Data Feed `json:"data"`
}
type Feed struct {
FeedData []<???> `json:"Feed"`
}
(真实的对象比较复杂,但这显示了想法(
如何为不同的 API 解析它,ut 有一些通用代码和一些基于高级数据(例如成功(的逻辑?
编辑:我正在扩展这个,以更多地解释我关于我正在寻找的"模式"的问题的扩展。
我想创建这个解析 API 组的包。然后,必须将DTO对象转移到其他一些对象中。这些"最终"对象在不同的包(实体包(中定义,然后必须持久化。
我现在想知道,如何将所有这些结合在一起:"最终"实体对象、从 DTO 到实体的转换函数、不同 API 的解析及其常见和不同的结果组件。
转换函数属于哪里(包明智(?
EDIT2:在深入研究问题后将源数据指定到切片(请参阅注释(
您可以将SourceDTO
结构嵌入到另一个结构中,如下所示:
type SourceDTO struct { // top level object
Success bool `json:"success"`
}
type FeedResponse struct {
FeedData YourCustomFeedStruct `json:"feed"`
// Embedded Struct
SourceDTO
}
现在,您可以从 FeedResponse 结构访问Success
布尔值。此外,SourceDTO
结构上定义的任何方法都可以从 FeedResponse 访问。
感谢@mkopriva对此解决方案的输入。
为了在 json 解组中进行一些抽象,可以在许多用例中使用interface{}
。
package main
import (
"encoding/json"
"fmt"
)
type UniversalDTO struct {
Success bool `json:"success"`
Data interface{} `json:"data"`
}
type ConcreteData struct {
Source string `json:"source"`
Site string `json:"site"`
}
func main() {
jsondata := []byte(`{"sucess":"true","data":[{"source":"foo","site":"bar"}]}`)
data := make([]ConcreteData, 0, 10)
dtoToSend := UniversalDTO{Data: &data}
describe(dtoToSend)
describe(dtoToSend.Data)
json.Unmarshal(jsondata, &dtoToSend)
describe(dtoToSend)
describe(dtoToSend.Data)
}
func describe(i interface{}) {
fmt.Printf("(%v, %T)n", i, i)
}
在这里测试:https://play.golang.org/p/SSSp_zptMVN
json.Unmarshal
期望将 JSON 放入其中的对象。因此,首先我们总是需要一个对象。根据目标对象的具体实例,接口{}可以用具体的结构对象覆盖(当然必须单独创建(。这里的一个重要学习是,Go接口也可以用切片覆盖。通过这种方式,还可以将数组解组为 go 对象。但是,结构的切片必须定义为指向该类型的指针切片。