Format Gorm struct to proper JSON

Hello!

I’m trying to set up an API using Gorm, it works smootly, however, my JSON format is not correct.

For instance, a GET request returns it with bad formatted.

[
  {
    "ID": 1,
    "CreatedAt": "2017-03-16T11:37:16.14044-05:00",
    "UpdatedAt": "2017-03-16T11:37:16.14044-05:00",
    "DeletedAt": null,
    "name": "Lions",
    "description": "This is the lions cohort"
  }
]

It should be

[
  {
    "id": 1,
    "created_at": "2017-03-16T11:37:16.14044-05:00",
    "updated_at": "2017-03-16T11:37:16.14044-05:00",
    "deleted_at": null,
    "name": "Lions",
    "description": "This is the lions cohort"
  }
]

And this is my struct:

package models

import "github.com/jinzhu/gorm"

// Cohort represents any given cohort in the site
type Cohort struct {
	gorm.Model
	Name        string `gorm:"type:varchar(40); unique_index; not null" json:"name"`
	Description string `gorm:"type:varchar(255); not null" json:"description"`
	Users       []User `json:"users,omitempty"`
}

Is this the correct approach?

package models

import "time"

// Cohort represents any given cohort in the site
type Cohort struct {
	ID          uint       `gorm:"primary_key" json:"id"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	DeletedAt   *time.Time `json:"deleted_at"`
	Name        string     `gorm:"type:varchar(40); unique_index; not null" json:"name"`
	Description string     `gorm:"type:varchar(255); not null" json:"description"`
	Users       []User     `json:"users,omitempty"`
}

Thank you so much!

1 Like

I think that should work.

My understanding is that gorm.Model was designed as a convenient way to add those fields to user defined models and is is no way required.

I think this not work because gorm.Model has not json field tags
https://godoc.org/github.com/jinzhu/gorm#Model

Then the last code can be work

My code works, but I wonder if it’s the right approach.

You could extract the fields in question to a separate struct and embed it, similar to what gorm is doing, if you’re going to be doing this in many types.

type commonModelFields struct {
	ID          uint       `gorm:"primary_key" json:"id"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	DeletedAt   *time.Time `json:"deleted_at"`
}

type Cohort struct {
    commonModelFields
	Name        string     `gorm:"type:varchar(40); unique_index; not null" json:"name"`
	Description string     `gorm:"type:varchar(255); not null" json:"description"`
	Users       []User     `json:"users,omitempty"`
}

But I don’t think there’s anything wrong with the other way either.

1 Like

Another approach is to maintain a separate type like your expanded Cohort type just for json output and then (manually) convert from one to the other when you need to produce json. The conversion has to be done manually because Go does not see an embedded struct as being equivalent to its expanded fields.

The risk I see with the manual expansion of gorm.Model is that it won’t keep pace with the actual gorm.Model. Assuming you have multiple models, it might be better to have your own Model type which is embedded in your models to make it easier to keep up with gorm’s Model

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.