通过JSON API将嵌套结构映射到具有相同数据的不同嵌套结构

时间:2016-05-17 02:12:32

标签: json api go struct

使用Go,我想接受带有json数据的请求,并将其转换为传出json请求的不同结构。

这是我的意思的一个例子:

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type Greetings struct {
    Greetings []Greeting `json:"data"`
}

type Greeting struct {
    From     string `json:"from"`
    To       string `json:"to"`
    Greeting string `json:"greeting"`
}

type RelationShip struct {
    Messages []Message `json:"data"`
}

type Message struct {
    From    string `json:"from"`
    To      string `json:"to"`
    Message string `json:"message"`
}

func main() {
    http.HandleFunc("/", Greet)
    http.ListenAndServe(":3000", nil)
}

func Greet(rw http.ResponseWriter, request *http.Request) {
    decoder := json.NewDecoder(request.Body)
    var greetings Greetings
    err := decoder.Decode(&greetings)
    if err != nil {
        panic(err)
    }
    for _, g := range greetings.Greetings {
        fmt.Printf("%s, to %s from %s.\n", g.Greeting, g.To, g.From)
    }

    relationShip := &RelationShip{Messages: greetings.Greetings}
    r, err := json.Marshal(&relationShip)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(r))
}

以下是curl请求的示例

curl -d '{"data": [{"to":"drew","from":"jo","greeting":"Hey"}, \
  {"to":"lori", "from":"yuri","greeting":"what up?"}]}' \
  http://localhost:3000

我想也许我可以逃脱类似的事情:

relationShip := &RelationShip{Messages: greetings.Greetings}

但我不能使用type [] Greeting作为type [] Message。我是Go的新手,也是一般的静态类型语言。我是否遍历问候列表并将它们作为新的消息项目推送到消息中?

要点:我正在编写一个可以接收传入请求的API,并将其发送到正确的第三方API,该API始终关注相同的数据,但可能有不同的密钥。因此,对实际问题和/或更好的方法的提示表示赞赏和欢迎:)

2 个答案:

答案 0 :(得分:1)

正如您所注意到的,您不能使用类型[]问候语作为类型[]消息。因为它们不是同一类型。但是,有一种方法可以从一种类型转换为另一种类型,但它需要identical种类型。

例如,以下内容可行:

type Message struct {
    From string    `json:"from"`
    To string      `json:"to"`
    Message string `json:"message"`
}

type Greeting struct {
    From string    `json:"from"`
    To string      `json:"to"`
    Message string `json:"message"`
}

func main() {
    mess := Message{"from", "to", "message"}
    fmt.Println(reflect.TypeOf(mess))
    // > Message
    greet := Greeting(mess)
    fmt.Println(reflect.TypeOf(greet))
    // > Greeting
}

但是,它要求字段相同,并且json标记也是如此。

在你的情况下,迭代问候并将它们转换成消息将毫无问题地工作。

答案 1 :(得分:0)

根据Jiang YD的评论,我更换了

relationShip := &RelationShip{Messages: greetings.Greetings}

以下内容:

var relationShip RelationShip
for _, g := range greetings.Greetings {
    relationShip.Messages = append(
        relationShip.Messages, Message{
            To: g.To, From: g.From, Message: g.Greeting,
        },
    )
}

我喜欢做什么。感谢您的反馈!