Skip to content

Handle specially API endpoints with only one successful response status code #276

Description

@mitar

When I generate API I get such response structure for our calls, example:

type GetClientResponse struct {
	Body         []byte
	HTTPResponse *http.Response
	JSON200      *AppClient
	JSON400      *ApiError
	JSON401      *ApiError
	JSON402      *ApiError
	JSON404      *ApiError
	JSON500      *ApiError
}

I would prefer something like:

type GetClientResponse struct {
	Body         []byte
	HTTPResponse *http.Response
	Success      *AppClient
	Error        *ApiError
}

First, I would not have to know exactly which 2xx status code is returned. Second, I can call response.StatusCode() to obtain the status code, there is no point in having that also part of the field name. Given that this for generating HTTP API it is pretty reasonable to assume 2xx codes are success and everything else is failure. So if there is only one successful response status code defined in the API, make it simply be named Success. And if all errors have the same type, collapse them as well into Error.

Currently I have to have such ugly code to make sense of this:

func getResponseError(response interface{}, statusCode int, body []byte) error {
	r := reflect.ValueOf(response)
	f := reflect.Indirect(r).FieldByName(fmt.Sprintf("JSON%d", statusCode))
	if !f.IsValid() {
		return errors.Errorf("Unexpected status code %d: %s", statusCode, body)
	} else if f.IsNil() {
		return errors.Errorf("Error response %d", statusCode)
	} else {
		errorMessage := f.Interface().(*ApiError).Error
		if errorMessage != nil {
			return errors.Errorf("Error response %d: %s", statusCode, *errorMessage)
		} else {
			return errors.Errorf("Error response %d", statusCode)
		}
	}
}

func GetAppClientFromResponse(response *GetClientResponse) (*AppClient, error) {
	if response.JSON200 != nil {
		return response.JSON200, nil
	} else {
		return nil, getResponseError(response, response.StatusCode(), response.Body)
	}
}

Alternatively, there could be some methods on the struct (for backwards compatibility) which would be returning those success or error values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions