YamlBox

Генераторы кода · 5 минута чтения

JSON to Go: структуры, которые демаршализуются с первой

Go заставляет вас записать форму JSON, которую вы декодируете, и компилятор удерживает вас за это. Преобразование JSON в Go из реального ответа исключает как ввод текста, так и догадки: имена полей, теги `json` и вложенные типы приходят корректно, и вы можете сразу перейти к той части программы, которая действительно что-то делает.

Обновлено

Созданная форма

Конвертер превращает каждый объект JSON в структуру, каждый массив в срез и выводит тип Go для каждого значения. Вложенные объекты становятся именованными типами, а не анонимными большими двоичными объектами, что обеспечивает читаемость подписи вашего кода декодирования:

                type Container struct {
  Name  string `json:"name"`
  Image string `json:"image"`
  Ports []struct {
    ContainerPort int `json:"containerPort"`
  } `json:"ports"`
}
              

Теги `json` являются важной частью. Декодер Go нечувствителен к регистру при сопоставлении имен полей, но `containerPort` и `ContainerPort` не выравниваются без тега, и любой ключ, который не является действительным идентификатором Go — например, `app.kubernetes.io/name` — вообще не может быть сопоставлен без него.

Числа, нули и две классические ловушки

  • Числа — вывод выдает `int` для целых значений, но JSON не имеет целочисленного типа. Поле, которое сегодня имеет значение `3`, завтра может быть `3.5`, поэтому идентификаторы и деньги в большей безопасности, как `float64`, `string` или `json.Number`, в зависимости от ваших потребностей.
  • Нулевые значения — ключ, который может иметь значение `null`, должен быть указателем (`*string`), чтобы можно было отличить «отсутствует» от «пусто».
  • Временные метки — строка RFC 3339 аккуратно декодируется в `time.Time`; номер эпохи Unix не имеет значения, поэтому сохраните его как `int64` и преобразуйте явно.
  • Неизвестные поля — `json.Decoder` игнорирует дополнительные поля по умолчанию; используйте `DisallowUnknownFields`, если вы предпочитаете громко провалиться.

По возможности сгенерируйте из двух или трех ответов. Поля, которые иногда отсутствуют, становятся указателями, и это решение гораздо легче принять на основе фактов, чем на основе памяти.

От структуры к рабочему коду

При наличии структур декодирование занимает три строки, и компилятор определяет пути доступа оттуда. Распространенным шаблоном является декодирование в сгенерированную структуру, а затем сопоставление с типом вашего домена, чтобы форма JSON могла меняться, не меняясь в приложении. Пометьте сгенерированный файл конечной точкой, из которой он пришел, и перегенерируйте его при изменении ответа, а не редактируйте его вручную: сгенерированный вручную код — это версия, которую никто не осмеливается перегенерировать позже.

Генерировать локально

Полезные данные, из которых стоит генерировать структуры Go, обычно представляют собой реальные ответы API, а реальные ответы содержат токены и данные о клиентах. Преобразование JSON в Go на основе браузера сохраняет полезную нагрузку на вкладке — ни загрузка, ни вопрос о хранении — что делает создание производственных данных обычным шагом, а не исключением из политики.

JSON до конца — часто задаваемые вопросы

Почему мои структуры Go не декодируют JSON?

Имена полей в JSON редко точно совпадают с экспортированными именами Go, поэтому структура нуждается в тегах `json`. Выполните повторное создание с включенными тегами, подтвердите написание ключа, включая пунктуацию, и проверьте, должен ли декодер разрешать неизвестные поля.

Должны ли генерируемые числовые поля быть int или float64?

Используйте `float64` – или `json.Number`, когда точность имеет значение – для чего-либо из внешнего API, поскольку JSON не отличает целые числа от десятичных. Зарезервируйте `int` для значений, которыми вы управляете в целом.

Как мне обработать поле, которое иногда имеет значение NULL?

Сделайте его типом указателя, например `*string`, который кодирует как «ключ отсутствует», так и «ключ присутствует с нулевым значением», но при этом позволяет вам проверять реальное значение. Вместо этого поля без указателей автоматически становятся нулевыми значениями.

Инструменты, упомянутые в этом посте

Просмотрите полный список инструментов 19

Еще статьи для чтения

Все 19 публикации →