Учитывая следующий вход:Go - Изменить JSON на лету
"object": {
"array": [
{
"element_field_1": some_value_1,
"element_field_2": some_value_1,
... // More unknown fields
},
...
],
"object_field": foo,
... // Some more unknown fields
}
мне нужно перебирать каждый элемент массива, изменять поля 1 и 2, а затем выводит объект JSON. Вот что у меня есть сейчас, но она далека от действительного кода Go:
func handler(w http.ResponseWriter, r *http.Request) {
// Transform the request's body to an interface
j := getDecodedJSON(r)
// Iterate over every element of the array
for i := 0; i < len(j["object"]["array"]); i++ {
rewrite(j["object"]["array"][i])
}
// Encoding back to JSON shouldn't be a problem
}
func getDecodedJSON(r *http.Request) map[string]interface{} {
dec := json.NewDecoder(r.Body)
var j map[string]interface{}
if err := dec.Decode(&j); err != nil {
log.Fatal(err)
}
return j
}
func rewrite(element *map[string]interface{}) {
element["element_field_1"], element["element_field_2"] = lookupValues(element)
}
В основном ошибка:
invalid operation: j["object"]["array"] \
(type interface {} does not support indexing)
, но, конечно, есть более концептуальная ошибка в моем подходе.
Запись struct
, которая детализирует содержимое ввода, на самом деле не является вариантом, так как я заранее не знаю ключей JSON.
Как я могу это сделать «Путь»?
EDIT: Это фактическое использование случай:
- У меня есть два веб-службы, которые нуждаются в «переводчика» между ними.
- Служба 1 делает запрос к переводчику, где изменяется несколько полей, все остальное остается нетронутым.
- Затем переводчик принимает измененный JSON и повторяет запрос на обслуживание 2.
Другими словами, этот переводчик действует как человек в середине для обеих служб. Похоже, что это хороший вариант для этого, учитывая его быстрое время запуска и быструю обработку JSON.
Я не думаю, что имеет смысл подробно описывать каждое поле JSON в структуре Go, так как мне нужно только изменить несколько полей. Я готов сделать компромисс по эффективности из-за отражения (синтаксический анализ на map[string]interface{}
должен быть медленнее, чем использование полномасштабной структуры), в обмен на то, чтобы сделать код более общим для вариаций входа JSON.
Вы знаете типы неизвестных полей? – inf
@ дюймовый нет, не очень. Но если у вас есть обходное решение, связанное с пониманием типов, то, я думаю, я мог бы что-то сделать – jlhonora