GO: 导入一个结构体并将其重命名为json

huangapple go评论85阅读模式
英文:

GO: import a struct and rename it in json

问题

我用gorm在go中构建了一个数据库。为此,我创建了一个结构体,并使用该结构体创建了一个表。在后端一切正常,但在前端的问题是,JSON始终以大写形式返回ID,而swagger生成的ID是小写形式。在Go中,是否有一种方法可以用JSON标识符覆盖从gorm导入的结构体?

这个结构体给我以下响应:

{
    "ID": 8,
    "CreatedAt": "2022-11-15T20:45:16.83+01:00",
    "UpdatedAt": "2022-12-27T21:34:17.871+01:00",
    "DeletedAt": null,
    "createdBy": {
        "ID": 1,
        "CreatedAt": "2022-11-15T20:02:17.497+01:00",
        "UpdatedAt": "2022-11-15T20:02:17.497+01:00",
        ...
    },
    "archived": true
}

有没有办法使ID变为小写(像Archived一样)?或者我可以在swaggo中进行调整,以便以大写形式生成它。

我看到的是,你可以在不使用gorm.Model的情况下创建表,并自己定义所有属性。问题是,我必须自己创建这些列的所有功能(删除、更新、索引、主键等)。

英文:

I have built a database in go with gorm. For this I created a struct and with this struct I created a table. So far so good. In the backend everything works, but in the frontend the problem is that the JSON which is called always returns the ID in upper case and swagger generates me an ID which is lower case. Is there a way in Go that I can overwrite the imported struct from gorm with a JSON identifier?

import "gorm.io/gorm"

type Report struct {
   gorm.Model
   CreatedBy          User     `gorm:"foreignKey:CreatedByUserID" json:"createdBy"`
   Archived           bool     `json:"archived"`
}

This Struct gives me the following response

{
    "ID": 8,
    "CreatedAt": "2022-11-15T20:45:16.83+01:00",
    "UpdatedAt": "2022-12-27T21:34:17.871+01:00",
    "DeletedAt": null
    "createdBy": {
        "ID": 1,
        "CreatedAt": "2022-11-15T20:02:17.497+01:00",
        "UpdatedAt": "2022-11-15T20:02:17.497+01:00",
        ...
    },
    "archived": true,
}

Is there a way to make the ID lowercase (like Archived)? Or can I adjust it at swaggo so that it is generated in upper case.

What I have seen is that you can make the table without this gorm.Model and define all the attributes yourself. The problem is that I then have to create all the functionalities (delete, update, index, primary key, ...) of these columns myself.

答案1

得分: 1

我创建了自己的gorm-model-struct:

type GormModel struct {
	ID        uint           `gorm:"primarykey" json:"id"`
	CreatedAt time.Time      `json:"createdAt"`
	UpdatedAt time.Time      `json:"updatedAt"`
	DeletedAt gorm.DeletedAt `gorm:"index" json:"deletedAt"`
} //@name models.gormModel

我将这个结构体导入到其他结构体中:

type Report struct {
   GormModel
   CreatedBy          User     `gorm:"foreignKey:CreatedByUserID" json:"createdBy"`
   Archived           bool     `json:"archived"`
}

重要的是,你需要添加json键并设置属性名称。

英文:

I create my own gorm-model-struct:

type GormModel struct {
	ID        uint           `gorm:"primarykey" json:"id"`
	CreatedAt time.Time      `json:"createdAt"`
	UpdatedAt time.Time      `json:"updatedAt"`
	DeletedAt gorm.DeletedAt `gorm:"index" json:"deletedAt"`
} //@name models.gormModel

I import this struct into the other structs:

type Report struct {
   GormModel
   CreatedBy          User     `gorm:"foreignKey:CreatedByUserID" json:"createdBy"`
   Archived           bool     `json:"archived"`
}

Important is, that you add the json-key and set the attribute name.

答案2

得分: 0

你可以使用mapstructure包。

mapstructure是一个用于将通用映射值解码为结构体的Go库,反之亦然。

如果你想要在gorm.Model中嵌入ID字段,并带有自定义的json标签,并且你希望它在同一个结构体中而不是在一个"子结构体"中,你可以在嵌入模型上使用mapstructure:",squash"标签。

type Model struct {
	ID uint `json:"id"`
}

type Report struct {
	Model    `mapstructure:",squash"`
	Archived bool `json:"archived"`
}

func main() {
	input := map[string]interface{}{
		"id":       1,
		"archived": false,
	}

	var report Report
	if err := mapstructure.Decode(input, &report); err != nil {
		panic(err)
	}

	fmt.Println("Report ID:", report.ID)
	fmt.Println("Report ID via Model:", report.Model.ID)
}

正如你所看到的,使用mapstructure.Decode方法,你可以使用squash选项将映射转换为结构体,然后直接访问报告的ID。请注意,你仍然可以访问report.Model及其所有字段。

使用mapstructure,你可以将ID转换为小写,同时可以直接从report结构体中访问它,而不仅仅是从Model子结构体中访问。

英文:

You can use the mapstructure package.

> mapstructure is a Go library for decoding generic map values to structures and vice versa

If you want to embed ID field from gorm.Model with custom json tag, and you want it to be on the same struct and not in a "substruct", you can use mapstructure:",squash" tag on the embedded model.

type Model struct {
	ID uint `json:"id"`
}

type Report struct {
	Model    `mapstructure:",squash"`
	Archived bool `json:"archived"`
}

func main() {
	input := map[string]interface{}{
		"id":       1,
		"archived": false,
	}

	var report Report
	if err := mapstructure.Decode(input, &report); err != nil {
		panic(err)
	}

	fmt.Println("Report ID:", report.ID)
	fmt.Println("Report ID via Model:", report.Model.ID)
}

As you can observe, with mapstructure.Decode method you can convert map to struct with the squash option, and you can then access ID of report directly. Note that you can still access report.Model and all its fields.

With mapstructure, you can make the ID lowercase as you wanted, and also accessable from the report struct directly, not only from a Model substruct.

huangapple
  • 本文由 发表于 2022年12月29日 15:24:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/74948307.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定