簡體   English   中英

在呈現給jSON之前,如何將Golang結構的字段修改為其他類型?

[英]How to modify fields of a Golang struct to another type before rendering to jSON?

我們在帶有w / c API的API中添加了一個include參數,客戶端可以用來包含關系

// 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{}來做到這一點,就像在獲取數據庫中的事件之后,將事件結構轉換為map[string]interface{}並進行修改。 但是我想知道是否有一個更簡單的解決方案。

這是我嘗試使用map[string]interface{} : //play.golang.org/p/-19MWtqhE3的嘗試。 該代碼非常冗長。 這個想法是對每個結構使用map[string]interface{} ,然后組成包括相關資源的頂級資源。

有什么更好的方法?

我認為最干凈的方法是使用兩個不同的功能。

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();

要么

event.InformationsTeamIncluded();

您的代碼/示例中有些東西不是很合邏輯:

  • var Team1 ,因為結構中只有一個值,因此,如果您不打算在結構中添加一些Team ,我建議如果您計划將任何Team替換為Teams []*Team則將其替換為Team Teams []*Team
  • 第二件事是在您的示例中,您將兩個不同的值返回給同一個名稱,這取決於上下文,在一種情況下,我建議返回team1_id而不是team1

編輯 :沒有結構

func (e *Event) Informations() *map[string]interface{} {
    return &map[string]interface{}{
         "ID": e.ID,
         "Name": e.Name,
         "Team1": e.Team1,
    },
}

func (e *Event) InformationsTeamIncluded() *map[string]interface{} {
    // Reuse the previous function
    data := e.Informations()

    // Add the team1 informations
    data["team1"] = map[string]interface{}{
         ID: e.Team1.ID,
         Name: e.Team1.Name,
    }
    return data
}

實際上,您可以將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...)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM