I have an endpoint similar to GET ../produtcs/123
where 123 stands for an ID. The REST service response
- with either
status 200
and a json object A{"deliveryData": {"status": 200, ...}}
- or with
status 401
and a json object B{"error": "foo", "status": 401, ...}
There are similar question (1, 2, 3, 4) but in my case i can not change the endpoint that i have to call.
What i would like to know is how my go-client code to call this endpoint should handle the different responses?
Currently i return a string of the response
func getProductResponse(tokenResponse *TokenResponse, id string) (string, error) {
endpoint := "https://httpbin.org/json"
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return "Creation of Request failed", err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "client.Do(req) failed", err
}
defer func() {
if err := resp.Body.Close(); err != nil {
fmt.Println("Error closing response body:", err)
}
}()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
return "io.ReadAll(resp.Body) failed", err
}
return string(responseBody), nil
}
And the idea is to handle the response by something like this
func handleResponse(jsonStr string){
var product Product
var idError Error
if err := json.Unmarshal([]byte(jsonStr), &product); err == nil {
fmt.Println("JSON can be converted to Product")
} else if err := json.Unmarshal([]byte(jsonStr), &idError); err == nil {
fmt.Println("JSON can be converted to Error")
} else {
fmt.Println("JSON does not match either Product nor Error")
}
}
Example
productStr := `{"deliveryData": {"status": 200}}` // product found
idErrorStr := `{"error": "Id unknown", "status": 401}` // product not found
// id of product found
handleResponse(productStr)
// id not found
handleResponse(idErrorStr)
But i wonder if this is a bad design, since it does not take care of the different return types in the function that calls the endpoint.
How would you handle these two different responses?