Json 什么';Go中支持动态结构字段的干净解决方案是什么?

Json 什么';Go中支持动态结构字段的干净解决方案是什么?,json,rest,go,Json,Rest,Go,计划重构我们去年构建的应用程序的代码库。假设我们有一个包含相关资源的api端点w/c支持GET/api/leagues?include=sport。在api响应中,是否有更干净的方法使league资源的sport属性动态化?“运动”属性的值可以是int或sport结构。目前,我们正在做的是: // models/league.go type League struct { SportId int64 `json:"-"` Sport Sport `json:"-"` SportWra

计划重构我们去年构建的应用程序的代码库。假设我们有一个包含相关资源的api端点w/c支持
GET/api/leagues?include=sport
。在api响应中,是否有更干净的方法使
league
资源的
sport
属性动态化?“运动”属性的值可以是int或sport结构。目前,我们正在做的是:

// models/league.go
type League struct {
  SportId int64 `json:"-"`
  Sport Sport `json:"-"`
  SportWrapper interface{} `json:"sport"`
}

// controllers/league.go
include := c.Request.URL.Query().Get("include")
includes := strings.Split(include, ",")

for _, include := range includes {
  if include == "sport" {
    includeSport = true
  }
}

if includeSport {
  league.SportWrapper = league.Sport
} else {
  league.SportWrapper = league.SportId
}

c.JSON(http.StatusOK, league)
对api请求的响应:

{
  sport: {
    id: <id>,
    name: <name>
  }
}
{
运动:{
id:,
姓名:
}
}
也可以是:

{
  sport: <sport_id>
}
{
运动:
}

没有更多的上下文,很难说清楚。我假设SportId也是Sport结构的一部分。基本上只返回ID或整个结构

我建议只加上

Sport Sport `json:"-"`
结构。与直接将其序列化为json不同,您必须首先使用固定属性集创建一个映射(基本上是一个viewmodel)。在那里,您可以设置SportID或Sport struct,然后可以将映射序列化为json

这也不是一个很好的解决方案,但其优点是,在当前的解决方案中,响应代码的丑陋性会泄漏到数据模型中,从而泄漏到应用程序的其余部分。通过中间映射,丑陋的部分被限制在响应生成中

// models/league.go
type League struct {
  Sport Sport
}

... parse includes ...

viewModel := map[string]interface{}

if includeSport {
  viewModel["sport"] = league.Sport
} else {
  viewModel["sport"] = league.Sport.ID
}

c.JSON(http.StatusOK, viewModel)

如果您可以将请求参数设置为json,您可以使用它。

没有注意到我问题中的更新没有提前保存。我现在添加了更多的上下文以使我的问题更清楚。嗯,我想我明白你的意思了。我只是还不知道如何在代码中实现它。你能提供一个简单的例子吗?
// models/league.go
type League struct {
    SportID int64 `json:"-"`
    Sport Sport `json:"-"`
    SportWrapper interface{} `json:"sport"`
}


var (
    sportID int
    sport Sport
)
// controllers/league.go
include := c.Request.URL.Query().Get("include")
if err := json.Unmarshal([]byte(unclude), &sportID); err != nil {
    json.Unmarshal([]byte(unclude), &sport)
    league.SportWrapper = sport
    league.Sport = sport
} else {
    league.SportWrapper = sportID
    league.SportID = sportID
}

c.JSON(http.StatusOK, league)