Closed sebastiandemel closed 8 months ago
:+1: to the suggestion. As you mentioned, this would save A LOT of copy/paste.
Link to meta #566
Just a reminder, please use github reactions, rather than "+1" comments (two recent ones deleted).
Is there any progress with this? The ticket is open for more than 3 years now... :(
I cannot imagine why this is not fixed yet as this issue just makes impossible to specify an error for an invalid path (404) or method (405).
you can reference responses, which is more or less what is being requested here:
paths:
/my_endpoint:
get:
responses:
404:
$ref: "#/components/responses/notFound"
405:
$ref: "#/components/responses/methodNotAllowed"
/other:
get:
responses:
404:
$ref: "#/components/responses/notFound"
405:
$ref: "#/components/responses/methodNotAllowed"
components:
responses:
notFound:
description: "Not found response"
content":
application/json":
schema:
$ref: "#/components/schemas/notFoundResponse"
methodNotAllowed:
description: "Method Not Allowed response"
content":
application/json":
schema:
$ref: "#/components/schemas/methodNotAllowedResponse"
I know this is much more verbose, but at least is a workaround....
+1 dream about this feature
+1, will be useful
+1, amazing feature
+1, I will be gratefull
+1 this will save a lot of repeating docs code
+1 would save a lot of time
+1
this will be usefull
This would be incredibly useful and performance booster!
its so helpfull if this feature is exist
We have about 800 endpoints. Repeating the same error response references everywhere increases the JSON a lot...
I'm also wondering how this isn't a thing yet. There's so many responses that are just part of every single endpoint by default. Things like "content-type not supported", "invalid credentials", "request entity too large", "malformed content", and more... Are we not supposed to add these to the API at all? Or are we really supposed to add these manually to every endpoint?
Also, what about responses that aren't even tied to an endpoint at all? For example, an "endpoint does not exist" response? I obviously can't add that response to any of the endpoint definitions.
Maybe some of those are not supposed to be part of the API definition at all, but I'm using RFC 7807
for my error responses and I want to give a unique response for each error so that clients can switch on the type for error handling. Currently this is a big pain to do.
I'm currently looking at the possible need to add a default / override for the JSON Schema, $schema
$vocabulary
etc keywords in OAS 3.1
A design question comes up between simplicity and extensibility of this "default" feature.
Would something like:
openapi: 3.1.0
info:
title: API
version: 1.0.0
defaults:
responses:
'405':
description: Method not allowed
schema:
$ref: '#/components/responses/error'
'429':
description: Too many requests
schema:
$ref: '#/components/responses/error'
headers:
....
address the requirements for people in this issue? Bearing in mind @darrelmiller's very good advice in this tweet.
+1 for this feature!
I'm interested in that. Similar to what's been discussed so far in https://github.com/OAI/OpenAPI-Specification/issues/563
+1
@MikeRalphson With regards to the tweet: Does the spec already contain some language whether the defined responses should be exhaustive? When manually implementing an API client this information might be gathered from description texts or sources outside the openapi definition, but for code generation it is unclear, I think.
It would be really interesting to know whether people actually need to define common responses for all endpoints, or just some sensible fall-back handling for all kinds of undefined responses. If you like respond with :tada: for default handling would be enough and with :rocket: if having explicit definition for common responses would give you more.
I have an in-progress update to the Overlay specification to suggest enabling this method to apply defaults to an OpenAPI description using an Overlay.
#### Default Overlays Examples
Using wildcards and the `default` action, overlays can be used to provide default behavior.
```yaml
overlay: 1.0.0
info:
title: Provide defaults where objects don't exist
version: 1.0.0
updates:
- target: paths.*.get.responses.400
default:
description: Bad request
content:
application/http-problem:
schema:
$ref: "/components/schemas/badRequestProblem"
- target: paths.*.get.responses.404
default:
description: Not found
content:
application/http-problem:
schema:
$ref: "/components/schemas/notFoundProblem"
- target: paths.*.get.responses.5XX
default:
description: Server Error
content:
application/http-problem:
schema:
$ref: "/components/schemas/serverErrorProblem"
Would there be any way of indicating some default responses as a combination of status code + headers + body? For example 301 + Location, 400 + Content-Type: application/problem+json, 503 + Retry-After.
Common responses with http status codes, schemas, and example, or at least common errors, would be really great to have and would allow to focus endpoint description only on specific success responses and specific, meaningful error responses.
This is a must-have feature, and it's disappointing that the issue was opened back in 2015, and no lead still. Upvote!
you can reference responses, which is more or less what is being requested here:
paths: /my_endpoint: get: responses: 404: $ref: "#/components/responses/notFound" 405: $ref: "#/components/responses/methodNotAllowed" /other: get: responses: 404: $ref: "#/components/responses/notFound" 405: $ref: "#/components/responses/methodNotAllowed" components: responses: notFound: description: "Not found response" content": application/json": schema: $ref: "#/components/schemas/notFoundResponse" methodNotAllowed: description: "Method Not Allowed response" content": application/json": schema: $ref: "#/components/schemas/methodNotAllowedResponse"
I know this is much more verbose, but at least is a workaround....
This is an absolute nonsense, how a declared "GET /my_endpoint" could result in a 404 or 405, these errors only apply to the inverse set of declared endpoints, which is the infinite set of undeclared things.
Adding a global response might make the contract definition much more "implicit" and I get that. On the other hand this feature can be handy for many specific use cases.
For example:
I an developing a platform that generates server API from openAPI contract for developer which in turn will implement the contract.
The web server I use performs some validations on incoming requests (vertx-web-openapi
is the web server).
It would be nice if I can auto add that response to all new endpoints, something some developers using this platform will almost certainly won't, because this error itself is "implicit" in the code.
I am not sure if it is a good/bad idea to have this feature but there might be a solution in between.
+1 Surprised this is not implemented yet, this would save me lots of work
Any updates about this?
you can reference responses, which is more or less what is being requested here:
paths: /my_endpoint: get: responses: 404: $ref: "#/components/responses/notFound" 405: $ref: "#/components/responses/methodNotAllowed" /other: get: responses: 404: $ref: "#/components/responses/notFound" 405: $ref: "#/components/responses/methodNotAllowed" components: responses: notFound: description: "Not found response" content": application/json": schema: $ref: "#/components/schemas/notFoundResponse" methodNotAllowed: description: "Method Not Allowed response" content": application/json": schema: $ref: "#/components/schemas/methodNotAllowedResponse"
I know this is much more verbose, but at least is a workaround....
Its a workaround. But its still much the same(Copying and pasting). And in this case, adding one more error to all paths will be a headache.
This is an absolute nonsense, how a declared "GET /my_endpoint" could result in a 404 or 405, these errors only apply to the inverse set of declared endpoints, which is the infinite set of undeclared things.
I got 4 downvotes just because I said that if GET /my_endpoint
is a defined endpoint then it cannot result in a 404 or 405 which is... factual.
There is a proposal for enabling this via Overlays. https://github.com/OAI/Overlay-Specification/pull/17/files#diff-2df9558a570116ce439ac7523cbed07a4a3a1b14d29a21f01920eb09f33df370R198
This is an absolute nonsense, how a declared "GET /my_endpoint" could result in a 404 or 405, these errors only apply to the inverse set of declared endpoints, which is the infinite set of undeclared things.
I got 4 downvotes just because I said that if
GET /my_endpoint
is a defined endpoint then it cannot result in a 404 or 405 which is... factual.
How a GET could NOT result in a 404... please explain that... 🤔
How a GET could NOT result in a 404... please explain that... thinking
I cannot, because it could, I was indeed wrong about 404 (I was confusing resource / endpoint).
However there is still the 405 case.
How a GET could NOT result in a 404... please explain that... thinking
I cannot, because it could, I was indeed wrong about 404 (I was confusing resource / endpoint).
However there is still the 405 case.
405 stands for method-not-allowed
. So why this status is not allowed for GET /my_endpoint
?
405 stands for
method-not-allowed
. So why this status is not allowed forGET /my_endpoint
?
It is allowed, but why would you define GET /my_endpoint
if in the end it returns a 405 (GET not allowed) ?
People are always free to return whatever status code they'd like, so even if it wouldn't make sense, if they did it, should OpenAPI support documenting it or should it be disallowed?
I feel like the whole point of OpenAPI is to have a way of documenting the behavior of endpoints, even if it doesn't make sense.
I think it's a bit interesting what you mentioned about documenting "the infinite set of undeclared things". It's possible that could be useful as well...
I was assuming that "Default responses for all endpoints" would only apply to endpoints that have been declared, but maybe there is something useful in being able to declare defaults(?) for undeclared endpoints as well. Might not be worth the hassle until someone with that use-case chimes in, though.
I was assuming that "Default responses for all endpoints" would only apply to endpoints that have been declared, but maybe there is something useful in being able to declare defaults(?) for undeclared endpoints as well. Might not be worth the hassle until someone with that use-case chimes in, though.
"Default response" could also mean "Default response for anything, declared or not, under /
(i.e. matching /*
)".
And we could even go further with the possibility to declare defaults for a path pattern (i.e. other than the default /*
).
As previously mentionned, Overlay spec https://github.com/OAI/Overlay-Specification seems to not address this use case. AFAIU it allows to generate a new OAS spec with all "defaults" expanded to the targeted endpoints.
We're not really in the business of defining what's... not defined. Same way you don't have to define all response codes for any given operation (it's pointless in many cases). There's no benefit of defining what might come back from an unknown endpoint in case someone happens to hit it. If you want people to know what might be returned from such an endpoint, just define the endpoint.
IMO I also think that this is not a responsibility of OpenAPI. It can be achieved by creating another package and distribute that for reuse.
However, the problem is about the reuse.
Currently, we cannot use allOf
to combine responses.
And since the response body is application specific, any predefined responses cannot be reused.
For example, assume you have this shared spec:
# shared.yml
components:
responses:
201.Created:
description: Created
headers:
Location:
required: true
schema:
type: string
400.BadRequest:
description: Bad Request
You can reuse them if you don't need to modify or add response body:
paths:
/dummy:
get:
"201":
$ref: shared.yml#/components/responses/201.Created
But you can't reuse it if you need to specify your response body:
paths:
/dummy:
get:
"400":
allOf: # not valid OpenAPI spec
- $ref: shared.yml#/components/responses/400.BadRequest
- responseBody:
...
Seems like right now the only way to get this to work is using Overlay. But that is not implemented in the wild and is very complicated.
Another workaround if you love copy and paste is to define all possible http operations and only define 405 as a valid response code.
{
"openapi": "3.0.3",
"info": {},
"paths": {
"/v1/the-best-api-endpoint": {
"trace": {
"responses": {
"405": {
"description": "method not allowed",
"content": {
"application/json": {
"schema": {
"message": "you can't submit this request"
}
}
}
}
}
},
"options": {
"responses": {
"405": {
"description": "method not allowed",
"content": {
"application/json": {
"schema": {
"message": "you can't submit this request"
}
}
}
}
}
},
"patch": {
"responses": {
"405": {
"description": "method not allowed",
"content": {
"application/json": {
"schema": {
"message": "you can't submit this request"
}
}
}
}
}
},
"get": {
"parameters": {},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"thing": ""
}
}
}
},
"500": {
"description": "Server Error",
"content": {
"application/problem+json": {
"schema": {
"errorDetails": ""
}
}
}
}
}
}
}
}
}
We currently (3.0) using the go to method to achieve "less" copy past:
Definition:
components:
responses:
401:
description: |
The authorization header is missing
The authorization token used is not valid
content:
application/json:
schema:
type: object
properties:
code:
type: number
example: 401
message:
type: string
example: 'Unauthorized'
content:
type: string
example: 'The reason for the refusal'
Usage:
paths:
/url:
get:
responses:
401:
$ref: '#/components/responses/401'
And to "customize default responses" we sneak them in as components/schemas not components/responses as you can't override response content https://github.com/OAI/OpenAPI-Specification/issues/521#issuecomment-1234713377 as you actually can in schemas:
Definition:
components:
schemas:
401:
type: object
properties:
code:
type: number
example: 401
message:
type: string
example: 'Unauthorized'
content:
type: string
example: 'The reason for the refusal'
Usage:
paths:
/url:
get:
responses:
401:
description: |
The authorization header is missing
The authorization token used is not valid
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/401'
- type: object
required:
- content
properties:
content:
type: string
example: 'Something else than: The reason for the refusal'
So we may have both if really necessary.. but native support would be much appreciated.. pretty please with extra sugar on? ;-)
I'm confused, sorry. Native support for what exactly? You can't use allOf
outside a schema, and this is very unlikely to change.
I'm confused, sorry. Native support for what exactly? You can't use
allOf
outside a schema, and this is very unlikely to change.
For us it makes "no sense" to distinguishe between schemas and responses. (depending on usecase)
so why is it that
I would like to see either the possibility to customize responses (somewhat) like schemas or to mark schemas as responses (so the won't be seen as DTOs) (hence native support)
I'm afraid I still don't follow. A response
object is basically a lightweight wrapper around one or more schema
objects. What is it you can't do today?
Maybe i'am bad with explanations :D .. i wan't to achieve what comment https://github.com/OAI/OpenAPI-Specification/issues/521#issuecomment-1234713377 says it can't be done ;)
@DerDu unfortunately that comment has a ...
in the example just where it would explain what it is trying to achieve....
that comment has a
...
in the example just where it would explain what it is trying to achieve
Hi, the ...
literally means adding anything specific for that usage.
Using that example, 400.BadRequest
only describes the HTTP Status that it is a bad request.
i.e. the user pass in something that does not recognized or accepted by the endpoint.
What could they be? That's specific to every usage.
e.g. customer-id
is missing, item-count
can't be negative number, etc.
Without the ability to use allOf
at the response level,
none of the response can be reused when we need to do any customization tailors to each usage.
I suggest that we add "default responses" that can be defined as default response for All endpoints. This would avoid copy-paste for some common responses like:
429 Too Many Requests 405 Method Not Allowed
The format could be
Or if flexibility is required, we could alter the default response keyword to take a list of responsedefinitions. This could benefit with the response code range proposal (https://github.com/swagger-api/swagger-spec/issues/516).
this would require some changes to the default response keyword.