What's the best way to ignore a field on Marshal, but not Unmarshal

I am using a Go API to access my SQL tables. My tables all have created_at and updated_at fields, and I would like those fields to be controlled by SQL, not Go. So for example:

query, err := GetObjects[SomeSchema]("table_name") // calls table, then unmarshals into []SomeSchema
assert.Equal(query[0], SomeSchema{id: "whatever", created_at: /* some time object */, updated_at: ... })

What I would like is to define a simple way to ignore the created_at and updated_at fields in all such schema objects on marshal, so that they do not override the SQL values, but they are read in as normal on unmarshal.

I was hoping an embedded struct with the two *time.Time objects would fix it, so that it ignores for marshal, but alas, the MarshalJSON() override is promoted to the parent object. As I understand it, the easiest way I know is, which is not easy since I have a lot of objects, to write a custom MarshalJSON() for each of my 10+ structs, which looks like:

func (s SomeSchema) MarshalJSON() ([]byte, error) {
    type SomeSchemaWithoutThoseFields struct {
        Id string `json:"id"
    }
    return json.Marshal(SomeSchemaWithoutThoseFields{id: s.Id})
}

Is there an easier, more idiomatic way to do this?

One approach you can take to achieve this is by using struct composition and embedding the struct that includes the fields you want to exclude from JSON marshalling. Here’s an example:

goCopy code

type Timestamps struct {
    CreatedAt time.Time `json:"-"`
    UpdatedAt time.Time `json:"-"`
}

type SomeSchema struct {
    Timestamps
    ID string `json:"id"`
    // Other fields...
}

In this approach, Timestamps is embedded within SomeSchema, but the fields CreatedAt and UpdatedAt are tagged with json:"-", indicating to the JSON marshaller that they should be ignored during marshalling.

This way, you don’t need to write custom MarshalJSON() methods for each struct, and the fields will be ignored during marshalling while still being read in as normal during unmarshalling.