Как лучше пропустить поле при конвертации структуры в JSON?

Ссылка скопирована
Go
1 ответ

Есть структуры

type Object struct { UpdatedAt time.Time } type MyObject struct { Object UpdatedAt time.Time `json:"-"` Price int }

Выполняю следующий код

myOb = MyObject{} myOb.UpdatedAt = time.Now() myOb.Price = 100 json.Marshal(myOb)

По вводным: в результате получает json

{ "UpdatedAt" : "0001-01-01T00:00:00Z", "Price": 100 }

Каким способом исключить поле UpdatedAt из результата?

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Артём Dev Ответ

В Go тег json:"-" нужно ставить на то поле, которое реально попадает в JSON. В вашем примере есть встраивание структуры Object, и поле UpdatedAt из неё продвигается в верхний уровень. А отдельное поле UpdatedAt time.Time json:"-" не обязательно перекрывает поведение так, как вы ожидаете.

Если хотите скрыть UpdatedAt из embedded-структуры, самый простой путь — не встраивать Object анонимно, а сделать его именованным или описать DTO отдельно:

type Object struct {
    UpdatedAt time.Time
}
 
type MyObject struct {
    Object Object `json:"-"`
    Price  int    `json:"Price"`
}

type Object struct { UpdatedAt time.Time } type MyObject struct { Object Object `json:"-"` Price int `json:"Price"` }

Если нужно сохранить встраивание для кода, но не отдавать поле в JSON, лучше сделать отдельную структуру ответа:

type MyObject struct {
    Object
    Price int
}
 
type MyObjectResponse struct {
    Price int `json:"Price"`
}
 
resp := MyObjectResponse{Price: myOb.Price}
json.Marshal(resp)

type MyObject struct { Object Price int } type MyObjectResponse struct { Price int `json:"Price"` } resp := MyObjectResponse{Price: myOb.Price} json.Marshal(resp)

Это нормальная практика: доменная модель отдельно, JSON DTO отдельно. Так меньше сюрпризов с embedded fields.

Ещё вариант — реализовать MarshalJSON вручную:

func (m MyObject) MarshalJSON() ([]byte, error) {
    type Alias struct {
        Price int `json:"Price"`
    }
    return json.Marshal(Alias{Price: m.Price})
}

func (m MyObject) MarshalJSON() ([]byte, error) { type Alias struct { Price int `json:"Price"` } return json.Marshal(Alias{Price: m.Price}) }

Итог: не пытайтесь перекрывать promoted field вторым полем с тем же именем. Для чистого JSON используйте отдельный DTO или ручной MarshalJSON. Это предсказуемее, особенно когда есть embedded-структуры.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно