Как я объединил и проверил два файла JSON в Go

Как я объединил и проверил два файла JSON в Go

25 июня 2025 г.

Когда я начал учиться Go, моей первой реальной задачей было объединить два файла JSON и подтвердить результат. Это звучало легко. Это оказался отличным способом узнать, как GO, ввод -вывод, JSON, MAPS и Type File Randles File.

Вот как я это сделал, что я узнал, и некоторые альтернативы, которые я нашел на этом пути.

Задача

  1. Прочитайте два файла JSON.
  2. Объединить их в единую структуру.
  3. Проверить результат, чтобы убедиться, что определенные поля существуют и имеют правильный тип.
  4. Напишите окончательный JSON в новый файл.

Шаг 1: чтение файлов JSON

Go имеет отличную поддержку для чтения файлов и декодирования JSON, используя только стандартную библиотеку.

data1, _ := ioutil.ReadFile("file1.json")
data2, _ := ioutil.ReadFile("file2.json")

var json1 map[string]interface{}
var json2 map[string]interface{}

json.Unmarshal(data1, &json1)
json.Unmarshal(data2, &json2)

Примечание: в новых версиях Go вы можете использоватьos.ReadFileвместоioutil.ReadFile, сioutilустарел.

Шаг 2: слияние карт JSON

Мне нужна была функция, чтобы объединить две карты. Если в обеих картах существовал ключ, значение со второй карты должно перезаписать первое. Если значение было вложенным объектом, мне нужно было рекурсивно объединить его.

Вот функция, которую я написал:

func mergeMaps(m1, m2 map[string]interface{}) map[string]interface{} {
    for k, v2 := range m2 {
        if v1, ok := m1[k]; ok {
            if v1Map, ok := v1.(map[string]interface{}); ok {
                if v2Map, ok := v2.(map[string]interface{}); ok {
                    m1[k] = mergeMaps(v1Map, v2Map)
                    continue
                }
            }
        }
        m1[k] = v2
    }
    return m1
}

Это обработало как плоские, так и вложенные структуры JSON правильно.

Шаг 3: проверка JSON

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

func validateJSON(data map[string]interface{}) error {
    if _, ok := data["name"].(string); !ok {
        return fmt.Errorf("missing or invalid 'name' field")
    }

    if port, ok := data["port"]; !ok || reflect.TypeOf(port).Kind() != reflect.Float64 {
        return fmt.Errorf("missing or invalid 'port' field")
    }

    return nil
}

Примечание: при расшифровании JSON вinterface{}цифры рассматриваются какfloat64по умолчанию, что может сначала сбивать с толку.

Шаг 4: Написание результата

Наконец, я написал объединенный и проверенный JSON обратно в файл, используя красивое форматирование.

resultBytes, _ := json.MarshalIndent(merged, "", "  ")
ioutil.WriteFile("merged_output.json", resultBytes, 0644)

Это работало точно так же, как и ожидалось.

Альтернативы: Использование пакета для объединения JSON

Позже я обнаружил, что некоторые пакеты облегчают слияние JSON. Это несколько хороших:

1mergo

mergoэто популярная библиотека для слияния карт и структур в ходе. Он поддерживает вложенные слияния и позволяет выбирать, перезаписать значения.

Установить:

go get github.com/imdario/mergo

Пример:

var a map[string]interface{}
var b map[string]interface{}

json.Unmarshal([]byte(`{"config": {"debug": false}}`), &a)
json.Unmarshal([]byte(`{"config": {"debug": true, "port": 8080}}`), &b)

mergo.Merge(&a, b, mergo.WithOverride)

Используйте это, если вы хотите чисто, глубоко слияние без записи рекурсивного кода.

2json-patch(Go-Patch)

json-patchПозволяет применять операции JSON Patch. Это больше для разнообразия и применения структурированных обновлений, но все же полезно для динамической работы с JSON.

Установить:

go get github.com/evanphx/json-patch

Используйте это, если вы работаете с патчами или хотите программно обновить JSON с помощью управления.

3mapstructure

mapstructureПомогает декодировать динамические карты в сильно напечатанные структуры. Это не инструмент слияния сам по себе, но хорошо работает после того, как вы объединяете данные JSON и хотите связать их с go struct.

Установить:

go get github.com/mitchellh/mapstructure

Используйте это, когда вы хотите структуру и безопасность типа после анализа JSON.

Последние мысли

Эта задача помогла мне многое узнать о том, как GO обрабатывает данные, как работает JSON под капюшоном, и почему сильная печатана имеет значение. Написание функции слияния дало мне контроль, но использование таких библиотек, какmergoСделал код более поддерживаемым позже.

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

Это небольшой проект, но тот, который меня многому научил.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE