Skip to content

Extending status code key field in a response by a reason code #1482

Open
@andy-maier

Description

@andy-maier

In a number of APIs that we have in the company, error responses for HTTP status 4XX and 5XX contain a message and a reason code. A particular HTTP status, say 400, usually has multiple reason codes. The reason codes are not globally unique, but the combination of an HTTP status code and reason code is unique and corresponds to a particular message (or rather message template, because there can be variables in it). Let's ignore the messages for a moment, but talk about the reason code.

My goal is to describe for each HTTP interaction (i.e. path & method) what the possible combinations of status code & reason code are that can happen for that specific interaction, and to have a description field for each such combination.

Second, I'd like the definitions of the complete set of defined combinations of status code and reason code along with its descriptions to be global, so that the definition of each response would only reference items from that global definition. There is a related issue #567.

Neither OpenAPI 2.0 nor 3.0 allows for the possibility to specify a combination of status code and reason code for a response. In the following excerpt of an OpenAPI 2.0 yaml file, I am using /definitions to define the format for error responses, and /responses to define the combinations of status code and reason code globally (messages / descriptions are left out for now), e.g. the response with key "error-400.1" stands for the combination of HTTP status code 400 and reason code 1. In the responses dictionary of an interaction (path+method), I want to reference the global /responses items that apply to this particular interaction:

{
    "definitions": {
        "error_response": {
            "type": "object"
            "properties": {
                "http-status": {
                    "format": "int32",
                    "type": "integer"
                },
                "reason": {
                    "format": "int32",
                    "type": "integer"
                },
            },
            "required": [
                "http-status",
                "reason",
            ],
        },
    },
    "responses": {
        "error-400.1": {
            "schema": {
                "$ref": "#/definitions/error_response"
            }
            "examples": {
                "application/json": {
                    "http-status": 400,
                    "reason": 1
                }
            },
        },
    },
    "paths": {
        "/api-tokens": {
            "post": {
                "summary": "Create an API token",
                "responses": {
                    "400.1": {                    # mark 1
                        "$ref": "#/responses/error-400.1"
                    }
                },
            }
        }
    },
}

The "mark 1" line is reported by the Swagger editor as an issue because the format of the key "400.1" is invalid. Reading the OpenAPI 3.0 spec, I find that the editor's reported issue is consistent with the spec, which defines that key as the HTTP status code or "default".

I think it is quite limiting to assign a fixed meaning to a dictionary key. In many other places, OpenAPI dictionary keys can be freely chosen and referenced. If that was possible with this key, the key could be a combination of status code and reason code, as I intended to do.

The extensibility mechanism of OpenAPI also does not help here I'm afraid, because all it can do is add extension fields to an already existing object. But in this case, the problem is that the meaning of the key (along with its checking in the editor) forces me to have only one object where I'd like to have multiple objects.

I think addressing this need is a hard problem given the format is as it is. For the record and for future consideration, I'd like to point out how limiting it was to assign a meaning to the key in this way, instead of allowing user-defined strings for the key and moving the status code into the object.

One possibility I'd like to bring up for discussion might be to simply allow user-defined strings starting with "x-" as keys (in lines such as "mark 1"), in addition to the already allowed status code values and "default". These user-defined strings could then be left alone by the editor or any tools that otherwise can continue to interpret a number as the HTTP status code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    error descDescribing error responses beyond error codes and response schemas

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions