Swagger – Specify Optional Object Property or Multiple Responses

swagger

I have an API that either returns the following response on success:

{
    "result": "success",
    "filename": "my-filename.txt"
}

or something like below upon failure:

{
    "result": "error",
    "message": "You must specify the xxx parameter."
}

The filename property is only specified if the request was a success, but a message is provided if there was an error. This means the message and the filename properties are "optional" but the result property is required.

I tried defining this response object in a definition as shown below:

"my_response_object": {
    "type": "object",
    "properties": {
        "result": {
            "type": "string",
            "description": "value of 'success' or 'error', indicated whether was successful",
            "required": true
        },
        "message": {
            "type": "string",
            "description": "an error message if there was an issue",
            "required": false
        },
        "filename": {
            "type": "string",
            "description": "the filename to return if the request was successful",
            "required": false
        }
    }
}

But it appears that swagger does not like the "required" attribute and will show the following error message:

enter image description here

When I look at an example from swagger, they have the following layout where there are two different response definitions instead of one.

"responses": {
    "200": {
        "description": "Profile information for a user",
        "schema": {
            "$ref": "#/definitions/Profile"
        }
    },
    "default": {
        "description": "Unexpected error",
        "schema": {
            "$ref": "#/definitions/Error"
        }
    }
}

I could do this, but it appears that one cannot have multiple responses for the 200 error code. Does this mean that one has to use "default" for all error responses, and one can only have a single structure for all erroneous responses, or is there a way to specify that certain attributes are optional in definitions?

Best Answer

You're getting the error in the model, because that's not the way to define required properties.

The correct form would be:

    "my_response_object": {
        "type": "object",
        "required": [ "result" ],
        "properties": {
            "result": {
                "type": "string",
                "description": "value of 'success' or 'error', indicated whether was successful"
            },
            "message": {
                "type": "string",
                "description": "an error message if there was an issue"
            },
            "filename": {
                "type": "string",
                "description": "the filename to return if the request was successful"
            }
        }
    }

Anything not in the required property is assumed to be optional. Keep in mind that this implies that it's possible to get both message and filename.

You can then use this model for your 200 response.

However - when it comes to REST API design, this breaks one of the more common standards. The status codes, taken from the HTTP protocol are meant to convey the outcome of the operation. 2XX are used for successful responses, 4XX are for errors due to bad user input, 5XX are for problems on the server side (3XX are for redirects). What you're doing here, is tell the client - the operation was successful, but in fact, it can be an error.

If you can still modify the API, I'd highly recommend making that distinction using the status codes, even using the fine tuned distinctions such as 200 for a successful GET operation, 201 for successful POST (or creation) operation and so on, based on the definitions here - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.

Related Topic