I'm trying to document a model that always returns a custom response code and associated description. For a single HTTP response code, there could be multiple custom response codes. For example, a 400 response might include:
+===========+======+=============+
| HTTP Code | Code | Description |
+===========+======+=============+
| 400 | 1 | Error 1 |
+-----------+------+-------------+
| 400 | 2 | Error 2 |
+-----------+------+-------------+
| 400 | 3 | Error 3 |
+-----------+------+-------------+
I could document that a 400 status returns an "Error" object that has "Code" and "Description". But I'd like to include all of the custom status codes in the documentation if that's even possible. Is it possible? If so, how would I go about doing this?
For anyone facing this problem nowadays, here's how I was able to solve it:
'422':
description: 'Unprocessable Entity'
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/SchemaForErrror1'
- $ref: '#/components/schemas/SchemaForErrror2'
examples:
Error1:
$ref: '#/components/examples/ExampleForError1'
Error2:
$ref: '#/components/examples/ExampleForError2'
Related
This question already has an answer here:
How not to copy-paste 3 generic error responses in almost all paths?
(1 answer)
Closed 8 months ago.
Currently I have something like this:
paths:
/home
...
responses:
200:
description: Successful operation
401:
$ref: '#/components/responses/401UnauthorizedDefault'
404:
$ref: '#/components/responses/404NotFound'
502:
$ref: '#/components/responses/502BadGatewayDefault'
/sign_up
...
responses:
201:
description: Created
401:
$ref: '#/components/responses/401UnauthorizedDefault'
404:
$ref: '#/components/responses/404NotFound'
502:
$ref: '#/components/responses/502BadGatewayDefault'
Is it possible to combine all three error responses and reference them with a $ref?
paths:
/home
...
responses:
200:
description: Successful operation
$ref: '#/components/responses/AllCommonErrorResponses’
/sign_up
...
responses:
201:
description: Created
$ref: '#/components/responses/AllCommonErrorResponses’
Currently I dont know all the error responses we will use. But there will be a set of shared. If we will extend them later, I dont want to go to every endpoint and adjust the responses.
OpenAPI v3 does not allow to reference a list of multiple responses.
You can use specific (e.g., "200") response codes or default for others.
There is no option to import a standard list of responses and reuse it.
If we follow the OAS3 spec for Response here we can see that each response status code can have multiple media types and each media type in turn has a schema particular to it.
UseCase : For example oas3 example below, we can see 200 has a binary stream response but 400 has 3 media-types:application/json, application/xml, text/plain.
So is the client expected to request accept-type header with all the media-types mentioned below. How can we have specific media-type for 400 response code, or basically how we can convey to the REST Service to respond with media type as application/xml when its a 400 bad request and if 200 is returning a binary stream.
Does this OAS3 response multiple media-type make sense for Client/Server Errors. If yes then whats the accept-type set for expecting, say "application/xml" for 400 bad request.
Please refer the below swagger UI snap. Where we see a drop-down for the media-types for error code as well. But when we try out executing the rest operations, the accept header is only populated as per the 200 status code's media-type
openapi: 3.0.0
info:
version: "1.0"
title: Resource
description: Resource service
paths:
/resource:
get:
summary: getResource
description: getResource
operationId: get-resource
responses:
"200":
description: a binary document to be returned
content:
application/octet-stream:
schema:
type: string
format: binary
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/Error400Element"
application/xml:
schema:
$ref: "#/components/schemas/Error400Element"
text/plain:
schema:
$ref: "#/components/schemas/Error400Element"
"500":
description: Internal Server Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error500Element"
application/xml:
schema:
$ref: "#/components/schemas/Error500Element"
text/plain:
schema:
$ref: "#/components/schemas/Error500Element"
servers:
- url: http://localhost:8088/
components:
schemas:
Error400Element:
type: object
required:
- name
properties:
name:
type: string
number:
type: integer
Error500Element:
type: object
properties:
number:
type: integer
flag:
type: boolean
EDIT : modified the OAS3 spec and the SwaggerUI
I defined my authentication in security and components/securitySchemes.
In the Swagger documentation about response, they provide this example:
paths:
/something:
get:
...
responses:
...
'401':
$ref: '#/components/responses/UnauthorizedError'
post:
...
responses:
...
'401':
$ref: '#/components/responses/UnauthorizedError'
...
components:
responses:
UnauthorizedError:
description: Authentication information is missing or invalid
headers:
WWW_Authenticate:
schema:
type: string
I have a lot more paths than two, and to access any of them, the client has to be authenticated. I would like to avoid the '401' definition for each path, and define it once globally, if it is possible somehow.
How is it possible to use this response for each path?
'401':
$ref: '#/components/responses/UnauthorizedError'
You can't, if you want the response to show up on that particular endpoint.
I avoid the repetition in favour of important errors by not adding them to each endpoint and instead putting the well understood standard responses - 401, 403, 429, 404, 503 - on either a status endpoint or on the root method. eg:
'/{foo}/{bar}/status':
get:
tags:
- api
responses:
'200':
description: successful response with a resource
content:
application/json:
schema:
$ref: '#/components/schemas/statusResponse'
'400':
$ref: '#/components/responses/400_error_response'
'401':
$ref: '#/components/responses/401_error_response'
'403':
$ref: '#/components/responses/403_error_response'
'404':
$ref: '#/components/responses/404_error_response'
'500':
$ref: '#/components/responses/500_error_response'
The boilerplate responses would then all refer to the standard responses.
Real endpoints then typically have a well defined response specific to that opearation and the things that may go specifically wrong.
'/{foo}/{bar}/segment':
post:
summary: checks username is found or not
description: |-
checks username and returns 204 if found else 403
operationId: checkUsername
tags:
- Login
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/segment_POST_request'
responses:
'200':
$ref: '#/components/responses/segment_POST_200_response'
'403':
$ref: '#/components/responses/403_forbidden_response'
'500':
$ref:
'#/components/responses/500_internal_server_error_replayable_response'
One thing I ensure is for error responses, the possible error codes for that operation are included in the response, like so:
500_internal_server_error_replayable_response:
description: |-
The following `500 Internal Server Error` errors can occur during the API processing.
| errorCode | cause | details |
| - | - | - |
| `SOME.ERROR.500` | There was an error processing the request either in Foo or on a downstream system | A request to something failed, Bar or Baz however the error is recoverable and can be replayed |
| `SOME.ERROR.014` | Baz returned a `404` during the migration operation, even though it has previously confirmed the member exists | This is a fatal error during the migration process and cannot be recovered. The request should not be replayed. |
headers:
content:
application/json:
schema:
$ref: '#/components/schemas/errorResponse'
example:
status: '500'
errorCode: SOME.ERROR.500
errorDescription: The request could not be processed
errorSubCode: ''
furtherDetails: ''
docLink: ''
Use an extension to add them in automatically as part of your build script.
What you're looking to do is not part of the OpenAPI standard. Responses are not inherited from parent objects; they must be explicitly added to every endpoint. You can include a $ref for each response, but with a well-defined spec with lots of endpoints, you'll end up with a lot of duplication, and it's likely an endpoint might miss a response or two over time as additions and modifications are made. Plus, it's simply not a good authoring experience.
To prevent this problem, add an extension to your responses, like this:
responses:
x-default-responses: true
'418':
description: Additional responses go here
The above spec will be the one that you work from. When done, have a script scan your completed yaml file, and replace that line with your list of default responses. Use this modified spec as the next stage of your development process (whatever it is you're using your OpenAPI spec for, be it documentation, testing, or SDK generation).
While you could have your script add the responses without the extension property (after all, it is just YAML you're writing), I recommend you don't do this. The extension makes your intent clear, so other editors will understand additional responses are present. Additionally, it is likely that (either now or one day in the future) you will have endpoints that do not conform to your default responses, so you wouldn't want to accidentally add those.
This is a simplified version of my OpenAPI 3.0 definition I'm viewing on the Swagger Editor online. I am trying to have the two responses for error codes 401 and 403, that share the same schema, show different examples - this doesn't seem to work and I still see the referenced type as example.
Can you help me figuring out what's wrong with the definitions?
openapi: 3.0.0
info:
version: '1.0'
title: A service
paths:
/doSomething:
post:
requestBody:
content:
application/json:
schema:
type: string
example: A string
responses:
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Denied'
components:
responses:
Unauthorized:
description: The endpoint cannot be reached because the request is not authorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: unauthorized
Denied:
description: The request's authorizations don't match the required ones needed to access the resource
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: permissions denied
schemas:
Error:
type: object
properties:
error:
type: string
Your definition is correct, and the response example show up in Swagger Editor 3.6.5+ and Swagger UI 3.17.4+. Also, multiple examples are supported in Swagger UI 3.23.0+ and Editor 3.6.31+.
I am not sure whether this is at the heart of your problem but I noticed that the HTTP status codes in your path respone sections aren't given enclosed in quotation marks. The OpenAPI specification v3.x (in contrast to v2.x) makes this mandatory which you might want to look up here:
https://swagger.io/specification/#responses-object
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#responses-object
I'm really struggling to understand the format of the examples section of a response. I have the following response defined for a 500 Internal Sever error.
500InternalServerError:
description: The server encountered an unexpected condition which prevented it from fulfilling the request
schema:
allOf:
- $ref: '#/definitions/Failure'
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
type: integer
examples:
application/json:
code: -1
message: The server encountered an unexpected condition which prevented it from fulfilling the request
When I load it up in swagger-ui, it looks like this:
How do I get the response to be formatted over multiple lines and look like this?:
{
"code": "-1",
"message": "The server encountered an unexpected condition which prevented it from fulfilling the request"
}
The lack of pretty print in the response-level examples seems to be a bug or missing functionality in Swagger UI 3.0.x. Feel free to submit an issue on GitHub.
The workaround is to use a schema-level example instead:
definitions:
Failure:
type: object
...
example:
code: "-1" # Quotes force the number to be treated as a string
message: The server encountered an unexpected condition which prevented it from fulfilling the request
By the way, you do not need allOf when using $ref alone (without combining it with other items):
schema:
$ref: '#/definitions/Failure'