Я прошу об этом Go encoding/json
, но я думаю, что это также относится к любым другим JSON-библиотекам, которые сопоставляют JSON-капли с объектами на любом языке.
Вот пример. Если вы хотите сократить URL-адрес с помощью API goo.gl URL shortener API, вы получите либо успешный ответ:
{
"kind": "urlshortener#url",
"id": "http://goo.gl/fbsS",
"longUrl": "http://www.google.com/"
}
Или ответ об ошибке:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required",
"locationType": "parameter",
"location": "resource.longUrl"
}
],
"code": 400,
"message": "Required"
}
}
Есть ли идиоматический способ справиться с этим - ответ, который может придерживаться двух совершенно разных схем?
Обычно я имею дело с JSON, используя карты/списки; Я знаю, что это возможно в Го. Я мог бы отключить map[string]interface{}
, а затем проверить, имеет ли карта "error"
в качестве ключа. Но тогда мне придется снова декодировать правильный struct
. (Я не прав?)
Я делаю что-то вроде этого. У меня есть один тип для каждого вида ответа:
type successResponse struct {
Kind string
Id string
LongUrl string
}
type errorResponse struct {
Error struct {
Errors []struct {
Domain string
Reason string
Message string
LocationType string
Location string
}
Code int
Message string
}
}
И декодирование выглядит следующим образом:
s := new(successResponse)
err := json.Unmarshal(blob, s)
if err == nil {
// handle success
} else {
e := new(errorResponse)
err = json.Unmarshal(blob, e)
if err == nil {
// handle error response
} else {
// handle actual error
}
}
Но это кажется уродливым. Как мне подойти к этому?