Json.unmarshal unknown response body

I call an API and the same API will respond with two different response structures
( contrary to docs… API Reference — Kea 2.0.1 documentation )

[ { "result": 0, "text": "Configuration successful." } ]

I have defined the following structure to unmarshal body response into:

type firstResponse []struct {
	Result int    `json:"result"`
	Text   string `json:"text"`
}

and

{ "result": 400, "text": "Bad Request" }

which I have also defined to unmarshal body response into:

type secondResponse struct {
	Result int    `json:"result"`
	Text   string `json:"text"`
}

What would be the best way to deal with this? Just a simple answer that points me in the right direction would be greatly appreciated.

I would also have to know which type of structure I used when I want to access this data.

Check the HTTP status code. If it’s 400 you probably got the second JSON in body.

I haven’t checked the documentation you linked, but it’s sad but true, that many API documentation only documents “success”, error handling is usually briefly described in a single paragraph, combining all the possible cases into a single sentence and a JSON object that carries little to no actual value…

1 Like

thanks for your answer… but my problem is actually dealing with the responses, as they are two different structures and I don’t know which will be returned.

I am seeking how to handle them. I guess I could:

  • use a chain of error checking to populate the correct structure
  • strip the array (if it exists) and there is a way to do this and place result in the secondResponse
  • add an array (if one does not exist) and there is a way to do this and place result in the firstResponse
  • convert response to string, add or remove array and convert to desired structure

Just asking for advise if there is some better way
I looked through golang json docs and nothing raised my eyes :man_shrugging:

Again, have you checked the HTTP status code of the response? If that corresponds with the code in the JSON, it should be easy to branch on that.

The alternative would be to unmarshal into interface{} first and use typeswitches to decide between top level object and top level list. And then convert the interface{} value into the struct. That will be very verbose code though.

2 Likes

ah yes, fortunately the “Bad Request” will return a 400. and the good a 200 so I can keep things clean.

A side note… would this be a bug with the code from the API as it returns two different types of structures?

It depends on their documentation.

In general APIs are untyped. It’s humans that give some semantic and syntactic meaning to binary blobs.

They provide a documentation that describes their part of the “contract”.

If they do things differently than in their documentation, then either the result is wrong or the documentation.

I do not have and will not read the linked document, as it’s just to much.

Though as I said already, the “everything went well” is often described as part of the endpoint documentation, while “something went wrong” has its own generic section which sadly is often very sparse.

cool, thanks for your help, I may make a mention of it to them on IRC.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.