@nurzhannogerbek

Как исправить проблему с функциями UnmarshalJSON и MarshalJSON?

Здравствуйте, товарищи! Помогите пожалуйста исправить проблему.

В базе данных PostgreSQL есть таблица.

CREATE TABLE SURVEYS(
  SURVEY_ID UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
  SURVEY_NAME VARCHAR NOT NULL,
  SURVEY_DESCRIPTION TEXT,
  START_PERIOD TIMESTAMP,
  END_PERIOD TIMESTAMP
);


Как вы можете заметить, последние 3 поля не обязательны для заполнения и могут хранить NULL.

На основе этой таблицы создал структуру в Golang:
type Survey struct {
	ID string `json:"survey_id"`
	Name string `json:"survey_name"`
	Description utils.NullString `json:"survey_description"`
	StartPeriod utils.NullTime `json:"start_period"`
	EndPeriod utils.NullTime `json:"end_period"`
}


В Golang приложении делаю GET запрос к определенной записи:
http://localhost:8000/api/survey/0cf1cf18-d5fd-474e-a8be-754fbdc89720


Получаю странный ответ:
{
    "survey_id": "0cf1cf18-d5fd-474e-a8be-754fbdc89720",
    "survey_name": "NAME",
    "survey_description": {
        "String": "DESCRIPTION",
        "Valid": true
    },
    "start_period": {
        "Time": "2019-01-01T00:00:00Z",
        "Valid": true
    },
    "end_period": {
        "Time": "0001-01-01T00:00:00Z",
        "Valid": false
    }
}


Необходимо получить такой ответ:
{
    "survey_id": "0cf1cf18-d5fd-474e-a8be-754fbdc89720",
    "survey_name": "NAME",
    "survey_description": "DESCRIPTION",
    "start_period": "2019-01-01 00:00:00",
    "end_period": null
}


Как правильно настроить MarshalJSON и MarshalJSON функции?

utils.go:
const layout = "2006-01-02 15:04:05"

type NullTime struct {
	pq.NullTime
}

func (nt *NullTime) Scan(value interface{}) error {
	nt.Time, nt.Valid = value.(time.Time)
	return nil
}

func (nt NullTime) Value() (driver.Value, error) {
	if !nt.Valid {
		return nil, nil
	}
	return nt.Time, nil
}

func (nt *NullTime) MarshalJSON() ([]byte, error) {
	if !nt.Valid {
		return []byte("null"), nil
	}
	val := fmt.Sprintf("\"%s\"", nt.Time.Format(layout))
	return []byte(val), nil
}

func (nt *NullTime) UnmarshalJSON(b []byte) error {
	err := json.Unmarshal(b, &nt.Time)
	nt.Valid = err == nil
	return err
}


type NullString struct {
	sql.NullString
}

func (ns *NullString) MarshalJSON() ([]byte, error) {
	if !ns.Valid {
		return []byte("null"), nil
	}
	return json.Marshal(ns.String)
}

func (ns *NullString) UnmarshalJSON(b []byte) error {
	err := json.Unmarshal(b, &ns.String)
	ns.Valid = err == nil
	return err
}
  • Вопрос задан
  • 512 просмотров
Пригласить эксперта
Ответы на вопрос 2
nikonor
@nikonor
Программист go, perl
самый просто вариант тупо сделать второй тип, куда конвертните полученный. в нем уже сделать логику.
Ответ написан
@falconandy
У вас поля структуры - это структуры utils.NullString и utils.NullTime, а MarshalJSON реализован для указателей на эти структуры. Просто уберите * в сигнатуре MarshalJS.

https://stackoverflow.com/questions/39164471/marsh...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы