Currently, OpenAPI allows us to identify the version of the API being described and deprecate operations using a Boolean value.
I would like to propose some additional metadata that makes it easier to track changes to APIs.
In addition to the existing deprecated flag, there is now a deprecatedVersion and replacementOperationId property.
Consider the following API and two of its operations:
{
"openapi" : "3.0.0",
"info" : {
"title" : "My API",
"version" : "1.0.313"
}
{
"/foo" : {
"get" : {
"operationId" : "getFoo",
"description" : "Return a foo",
"deprecated" : true,
"deprecatedVersion" : "1.0.312",
"replacementOperationId" : "getFoo2"
"responses" : {
"200" : {
"description" : "A foo representation"
}
}
},
"/foo2" : {
"get" : {
"operationId" : "getFoo2",
"description" : "Return a foo",
"responses" : {
"200" : {
"description" : "A completely different breaking foo representation"
}
}
}
}
}
}
The deprecatedVersion property indicates the API version in which this operation was deprecated. The replacementOperationId provides a pointer to a new operation that replaces the functionality of the deprecated operation.
These new properties enable a variety of useful capabilities:
Hmm, maybe also a field indicating until when an API will be supported?
@ePaul It would be nice if we can provide that information. However, how reliable is it going to be? And should it be a date, or should it be a version when it will be removed?
Anyway, I think support for this might have to wait, as we have higher priority breaking changes that we want to get resolved ASAP. We can always experiment with x- properties for stuff like this.
I just wanted to get the idea on record before I forgot it :-)
We would like to also be able to mark an entire API as deprecated. Repeating some internal discussion:
The simplest change to support this would be to add the "deprecated" property at the top level (the "root document object"). If the property is true, the API is deprecated; if not, it's still active.
For API deprecation, some additional information might be useful:
We would like to also be able to mark an entire API as deprecated. Repeating some internal discussion:
Came here to upvote this point. The scenario is all too common that you want to phase out v1 of an API end of next year in favor of v2 being released today. We should be able to mark this in the v1 spec document so contract-first clients and API generators can issue a loud warning pointing to the correct and supported API version.
version from #834, deprecatedVersion would refer to the version of the OpenAPI document, not the version of the API itself.I have been dealing with a similar thing in something I'm working on.
To add some of my thoughts: Lots of APIs don't have a single version, and imposing one would be tough. This should work for an evolving API with a version like "4.0.342" as suggested, but it also needs to work for URL versioned/namespaced APIs (as much as we hate em).
This is why date and version are both important.
Replacements are also interesting, because whilst it would often be ideal to say "this field is gone, use this one", sometimes fields just go without a replacement, or split or change fundamentally.
Pointing callers to the replacement field or the replacement endpoint is one thing, but we gotta send people somewhere when that is not an option... URL to docs? /shrug
just for completeness: while OpenAPI is about design time, it might be interesting to also consider runtime issues. for deprecating complete APIs, the HTTP Sunset header should be an RFC any minute now (https://tools.ietf.org/html/draft-wilde-sunset-header-10), and that could nicely complement any description information with real-time runtime signals.
i would refine @dret's comment above. There are two relevant HTTP headers for deprecation: Deprecation (https://tools.ietf.org/html/draft-dalal-deprecation-header-00) and Sunset. To inform about the deprecation, the Deprecation HTTP header should be used. To inform about sunset of the deprecated resource, the Sunset header should be used in addition to the Deprecation header. This is described in section #5 https://tools.ietf.org/html/draft-dalal-deprecation-header-00#section-5.
Draft #11 https://tools.ietf.org/html/draft-wilde-sunset-header-11 of the Sunset header clarifies this aspect as well in section 1.4 https://tools.ietf.org/html/draft-wilde-sunset-header-11#section-1.4.
yes, completely agree with @sdatspun2 here: HTTP Sunset is only for sunsets, and deprecation should be done with HTTP Deprecation.
Yep, now that both Sunset and Deprecation exist, there is not much need for further work on this. With OpenAPI mostly being used for design time, simply being able to say "This is now deprecated" is enough, as runtime code will sniff for deprecation.
For example, your OpenAPI generated Ruby SDK can just reference faraday-sunset and you will have an error in your logs or bug reporting system if an endpoint is suddenly sunset. Sniffing for deprecations is equally possible. I think all of this is more powerful than trying to get super specific about what might go away when in design time. :)
Allowing a Link Object for or instead of replacementOperationId adds the power of expressions to describing the vLatest call
It's a long time since my previous comment and for some reason I now love the idea of "replacementOperationId" : "getFoo2" or similar.
I can already imagine it being used in the new Stoplight docs we're cooking up, it'd be amazing for helping folks power through API evolution.
Design time is often considered something that happens first, then you build, then you run it, but that progression is not linear. In the design-first workflow, design happens first as the name suggests, but also the entire way through the lifecycle, with every new endpoint or property being added to the design over time.
As such it's perfectly normal for runtime code to emit deprecation and sunset headers, those headers could even be powered by a middleware that looks for these deprecation flags in OpenAPI. Seeing as The Stoplight Way is to have your OpenAPI and code in the same repo, this would be incredibly easy to do, and stop the duplication of information between having to add the deprecation flag in the description and then also add it in the code... 馃
What do folks think?
Most helpful comment
We would like to also be able to mark an entire API as deprecated. Repeating some internal discussion:
The simplest change to support this would be to add the "deprecated" property at the top level (the "root document object"). If the property is true, the API is deprecated; if not, it's still active.
For API deprecation, some additional information might be useful: