Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Default responses for all endpoints #521

Closed
sebastiandemel opened this issue Dec 5, 2015 · 64 comments
Closed

Proposal: Default responses for all endpoints #521

sebastiandemel opened this issue Dec 5, 2015 · 64 comments
Labels
Moved to Moonwalk Issues that can be closed or migrated as being addressed in Moonwalk re-use: globals/defaults Default or global components that can be overridden in some way

Comments

@sebastiandemel
Copy link

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

produces:
  - application/json
responses:
  '429':
    description: to many requests in the given timeframe
    schema:
      $ref: '#/definitions/error'
paths:
...

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 (#516).

responseDefinitions:
 "success":
    description: request successful
    code: 200
  "request limit":
    description: to many requests in the given timeframe
    code: 429, 419
    schema:
      $ref: '#/definitions/error'
  "server error":
    description: server error
    code: 500 - 599
    schema:
      $ref: '#/definitions/error'

paths
  test:
    get:
      responses:
        default:
         - "success"
         - "request limit"
         - "server error"

this would require some changes to the default response keyword.

@sebastiandemel sebastiandemel changed the title Proposal: Default error responses for all endpoints Proposal: Default responses for all endpoints Dec 7, 2015
@mrname
Copy link

mrname commented Dec 31, 2015

👍 to the suggestion. As you mentioned, this would save A LOT of copy/paste.

@jharmn
Copy link
Contributor

jharmn commented Feb 16, 2016

Link to meta #566

@OAI OAI deleted a comment from pawelryznar Aug 3, 2018
@OAI OAI deleted a comment from marcelion Aug 3, 2018
@MikeRalphson
Copy link
Member

MikeRalphson commented Aug 3, 2018

Just a reminder, please use github reactions, rather than "+1" comments (two recent ones deleted).

@OAI OAI deleted a comment from pawelryznar Aug 9, 2018
@marmax
Copy link

marmax commented Jun 12, 2019

Is there any progress with this? The ticket is open for more than 3 years now... :(

@NoiseByNorthwest
Copy link

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).

@nogates
Copy link

nogates commented Jul 19, 2019

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....

@saturov
Copy link

saturov commented Jan 16, 2020

+1 dream about this feature

@avsmirnov567
Copy link

+1, will be useful

@artem-zaitsev
Copy link

+1, amazing feature

@ozh-dev
Copy link

ozh-dev commented Jan 16, 2020

+1, I will be gratefull

@alexcambose
Copy link

+1 this will save a lot of repeating docs code

@Metroxe
Copy link

Metroxe commented Apr 26, 2020

+1 would save a lot of time

@matthiassb
Copy link

+1

@malotho-zz
Copy link

this will be usefull

@erdimeola
Copy link

This would be incredibly useful and performance booster!

@baguse
Copy link

baguse commented Jul 29, 2020

its so helpfull if this feature is exist

@Havunen
Copy link

Havunen commented Oct 21, 2020

We have about 800 endpoints. Repeating the same error response references everywhere increases the JSON a lot...

@Blacklands
Copy link

Blacklands commented Oct 21, 2020

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.

@MikeRalphson
Copy link
Member

MikeRalphson commented Oct 21, 2020

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.

@devdilson
Copy link

+1 for this feature!

@mxmlnglt
Copy link

mxmlnglt commented Jul 8, 2021

I'm interested in that. Similar to what's been discussed so far in #563

@DerDu
Copy link

DerDu commented May 2, 2023

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
#521 (comment)
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? ;-)

@MikeRalphson
Copy link
Member

I'm confused, sorry. Native support for what exactly? You can't use allOf outside a schema, and this is very unlikely to change.

@DerDu
Copy link

DerDu commented May 5, 2023

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)

  • Both "share the same" functionality in documentation (reuseability)
  • every response follows or is in itself a schema (definition)
  • and i can use both in response documentation. (usage)
    (maybe thats just my opinion/usecase)

so why is it that

  • schemas are customizable through e.g. allOf (mainly for return value examples)
  • and responses sadly not :-/ (specially refering to 200 and 201 examples most of the 3/4/5xx are defaults anyway)

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)

@MikeRalphson
Copy link
Member

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?

@DerDu
Copy link

DerDu commented May 5, 2023

Maybe i'am bad with explanations :D .. i wan't to achieve what comment #521 (comment) says it can't be done ;)

@MikeRalphson
Copy link
Member

@DerDu unfortunately that comment has a ... in the example just where it would explain what it is trying to achieve....

@unional
Copy link

unional commented May 5, 2023

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.

@jeremyfiel
Copy link
Contributor

jeremyfiel commented May 5, 2023 via email

@mxmlnglt
Copy link

mxmlnglt commented May 7, 2023 via email

@jeremyfiel
Copy link
Contributor

jeremyfiel commented May 7, 2023 via email

@unional
Copy link

unional commented May 7, 2023

Specifically, section 3.2:

https://datatracker.ietf.org/doc/html/rfc7807#section-3.2

@unional
Copy link

unional commented May 7, 2023

Also, even if you can come up with a generic data structure (error or normal response),
it only indicates the shape of the response, not the semantic of the response in a particular context.
That's when extension (using allOf or others) is important when reusing the generic data structure, while adding additional information about what can the response be.

Using rfc7807 as an example,
you can indicate it returns the data structure as described:

{
  "type": string,
  "title": string,
  "detail": ...
  ...
}

But what are the possible values for type? for detail?

Even if we don't change them to an enum or adding additional members, e.g. the balance and accounts in the example:

   {
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345",
                 "/account/67890"]
   }

At the minimum we should be able to add descriptions and other info on top of the common response.

Currently, the common response can only be used as-is, thus greatly limits its reusability.

@unional
Copy link

unional commented May 7, 2023

You can have additional fields because the schema is not constrained

Could be. But at the same time the API Spec fails to describe what the API actually returns.
Those additional fields are hidden and not mentioned in the spec.

i.e. the API Spec failed to serve as the documentation of the API.

@piotr-yuxuan
Copy link

fyi, this long-standing issue is addressed in: https://github.com/OAI/moonwalk

@rockymontana
Copy link

Not the way that I understand it… https://datatracker.ietf.org/doc/html/rfc7807 Grammar specifically says you can have additional fields.
On Fri 5 May 2023 at 20:42, Jeremy Fiel @.> wrote: RFC7807 error schema allows reuse of the same schema with the flexibility to apply different messages for each error in your service. You can create infinite examples of every possible error but the schema remains the same. On Fri, May 5, 2023, 14:21 Homa Wong @.> wrote: > 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. > > — > Reply to this email directly, view it on GitHub > < #521 (comment) >, > or unsubscribe > < https://github.com/notifications/unsubscribe-auth/AHU7MTK7B7VSUMGITXAZAU3XEVAKPANCNFSM4BV5WOKA > > . > You are receiving this because you commented.Message ID: > @.> > — Reply to this email directly, view it on GitHub <#521 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHCBEMMZ7NETJ2BIAZ7PHBDXEVCZPANCNFSM4BV5WOKA . You are receiving this because you are subscribed to this thread.Message ID: @.>

You might not want to give your your phone number and address publicly on Github?
You're basically doxxing yourself here 🤔
Sorry for hijacking the thread, carry on.

@mxmlnglt
Copy link

You might not want to give your your phone number and address publicly on Github? You're basically doxxing yourself here 🤔 Sorry for hijacking the thread, carry on.

Thanks for pointing this... that's the problem of answering by email. Fixed now. Thanks!!

@handrews handrews added re-use re-use: globals/defaults Default or global components that can be overridden in some way and removed re-use labels Jan 29, 2024
@andrew-rivera-dev
Copy link

I'm not sure why this rather simple proposal sparked so much debate. It only took working with OpenAPI for a few days for me to notice this gap when defining my API.

Nonetheless, it's not clear what the idiomatic way is for dealing with errors that are common to all your paths (401/403 is the simplest example). Defining these for every path just doesn't seem right.

If the spec was solely for documentation, I would say that error types that are truly universal to all your endpoints, and thus not surprising to callers of your API, are not even worth defining in your spec. But omitting errors that your API can return can have negative implications as soon as you start generating type safe clients with your spec.

This proposal is already 8 years old - how can we move it forward?

@ralfhandl
Copy link
Contributor

Would this be covered by the suggested apiResponses and pathResponses in the OpenAPI v4 (aka Moonwalk) Proposal?

@handrews handrews added the Moved to Moonwalk Issues that can be closed or migrated as being addressed in Moonwalk label Mar 14, 2024
@handrews
Copy link
Member

@ralfhandl yes, I think we can mark this "Moved to Moonwalk" and close it out here (Features added to Moonwalk will be back-ported to 3.x if it makes sense to do so, so there's no need to track it in both repositories).

@andrew-rivera-dev

I'm not sure why this rather simple proposal sparked so much debate.

This is a standards group, debating things that seem simple is practically a requirement 🙃 It's definitely frustrating at times, but I suspect this didn't get into 3.1 partially because there was a bit of a debate about how much we really even want to document all responses, but mostly because we had big things in 3.1 already and no one realized that the spec work would slow down so much afterwards. But it will find some sort of home in 4.0 (Moonwalk). And possibly to some degree in a future 3.x.

@piotr-yuxuan
Copy link

Thanks for clarifying!

@xmak
Copy link

xmak commented Nov 23, 2024

This is already possible to achieve using allOf. See here:

#563 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Moved to Moonwalk Issues that can be closed or migrated as being addressed in Moonwalk re-use: globals/defaults Default or global components that can be overridden in some way
Projects
None yet
Development

No branches or pull requests