如何在呈现为jSON之前将Golang结构的字段修改为另一种类型?

时间:2016-04-29 08:35:40

标签: rest go

我们在API中添加了一个include参数,客户可以使用API​​来包含关系

// request
GET /api/events?include=team1
[{
    "id": <event_id>,
    "name": <event_name>,
    "team1": {
        "id": <team_id>,
        "name": <team_name>
    }
}]

// code
type Event struct {
    ID int64 `gorm:"primary_key" json:"id"`
    Team1ID int64 `json:"-"`
    Team1 Team `json:"team1"`
}

var event Event
Db.Preload("Team1").Find(&event, 1)
c.JSON(http.StatusOK, event)

但我们也希望能够做到这一点:

// request
GET /api/events
[{
    "id": <event_id>,
    "name": <event_name>,
    "team1": <team1_id>
}]

team1字段现在只是一个id。

在Go中有一种简单的方法吗?

我想我可以使用map[string]interface{}来完成此操作,就像在db中获取事件后,将事件结构转换为map[string]interface{}并进行修改。但我想知道这是否更容易解决。

我尝试使用map[string]interface{} - https://play.golang.org/p/-19MWtqhE3。代码非常详细。我们的想法是为每个结构使用map[string]interface{},然后组成包含相关资源的顶级资源。

有什么更好的方法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

我认为最清洁的方法是使用两种不同的功能。

def connect(self):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(self.ip, port=self.port, username=self.user,password=self.password,timeout=self.timeout)
    time.sleep(10)
    return ssh

def runCommands(self,commands):
    ssh=self.connect()
    channel = ssh.invoke_shell()
    time.sleep(10)
    for command in commands:
        wait=0
        while channel.send_ready()!=True:
            wait+=1
            time.sleep(self.timeout)
            if wait==5:
                return 0
        channel.send(command+'\n')
    channel.send("exit\n")
    return 1

所以稍后再打电话

type Event struct {
    ID int64 `gorm:"primary_key" json:"id"`
    Team1ID int64 `json:"-"`
    Team1 Team `json:"team1"`
}

type Team struct {
    ID int64 `gorm:"primary_key" json:"id"`
    Name string `json:"name"`
}

type EventInformations struct {
    ID int64 `json:"id"`
    Name string `json:"name"`
    Team1 `json"team1"`
}

type EventInformationsTeamIncluded struct {
    ID int64 `json:"id"`
    Name string `json:"name"`
    Team1 Team `json:"team1"`
}

func (e *Event) Informations() *EventInformations {
    return &EventInformations{
         ID: e.ID,
         Name: e.Name,
         Team1: e.Team1,
    },
}

func (e *Event) InformationsTeamIncluded() *EventInformationsTeamIncluded {
    return &EventInformations{
         ID: e.ID,
         Name: e.Name,
         Team1: &Team{
             ...
         },
    }
}

event.Informations();

您的代码/示例中有一些不太符合逻辑的内容:

  • var event.InformationsTeamIncluded(); 有点奇怪,因为结构中只有一个值,所以如果你没有计划在struct中添加一些Team1,我建议将其替换为团队如果您打算让任何团队将其替换为Team
  • 在您的示例中,第二件事是将两个不同的值返回到同一个名称,这取决于我建议在一个案例中返回Teams []*Team而不是team1_id
  • 的上下文

编辑:没有结构

team1

答案 1 :(得分:1)

实际上,您可以将team1设置为接口,然后将其转换为值,显然可以进行正确的验证。

type Event struct {
    ID int64 `gorm:"primary_key" json:"id"`
    Team1ID int64 `json:"-"`
    Team1 interface{} `json:"team1"`
    Team1Struct Team `json:"-"`
}

然后评估:

if value, ok := evt.Team1.(Team); ok {
    // The passed value is a Team struct
    event.Team1Struct = value
} else {
    // The passed value is a string (or something else...)
}