Генераторы кода · 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`, который кодирует как «ключ отсутствует», так и «ключ присутствует с нулевым значением», но при этом позволяет вам проверять реальное значение. Вместо этого поля без указателей автоматически становятся нулевыми значениями.
Инструменты, упомянутые в этом посте
Еще статьи для чтения
6 минута чтения
От JSON до TypeScript: типы, соответствующие реальности
Преобразуйте интерфейсы JSON в TypeScript из реального ответа API — необязательные ключи, нулевые объединения, вложенные типы — и не допускайте смещения сгенерированных типов.
5 минута чтения
От JSON до SQL: от полезных данных к таблице, которую вы
Преобразуйте JSON в SQL с помощью операторов CREATE TABLE и INSERT, созданных на основе реальной полезной нагрузки, с разумным сопоставлением типов, экранированием и честными ограничениями.
6 минута чтения
JSON форматтер: красивый, минимизированный и действительно
Средство форматирования JSON, которое красиво печатает, минимизирует и проверяет точные местоположения ошибок, а также пять синтаксических ошибок, стоящих почти за каждой недопустимой ошибкой JSON.
- Более длинная статья для чтения: От JSON до TypeScript: типы, которые говорят правду