0

If I would have a resource on a certain URI, like https://api.example.com/things/my-things and so far this resource may be displayed on the following representations:

  • application/xml
  • application/xhtml+xml
  • text/xml
  • text/html

How SHOULD the server inform the clients asking for application/xml, application/xhtml+xml and text/xml that those are going to stop being supported as representation of the resource? Not right now, so a 406 Not Acceptable is not adequate.

I found a internet draft The Deprecation HTTP Header Field, but it is a internet draft, not a RFC, and I am not sure if this would be a valid implementation of the specification, or it would mean that the resource/URI is the one actually being deprecated.

Does anyone know a authoritative way to express that a representation of a resource is being deprecated, and is going to reach its sunset, but the URI would still be available with a different set of representations available?

  • https://datatracker.ietf.org/doc/html/rfc8594 should be reviewed. Like Deprecation, the language is centered on the resource, not the representation. – VoiceOfUnreason Jun 25 '21 at 20:38
  • Thanks @VoiceOfUnreason . I was already unsure if it would be a valid thing to do, but the main question remains: how to inform the deprecation of a representation? – theoamonteiro Jun 26 '21 at 17:34
  • I would use `301 Moved Permanantly` to indicate those URLs are outdated, providing a `Location` header to the 1 remaining URL. – Remy Lebeau Jun 28 '21 at 21:26
  • @RemyLebeau the URI (ex.: `https://api.example.com/things/my-things`) is not going to change. All that I want is a way to give clients a "heads up" that some formats on the `Accept`h eader (ex.: `application/xhtml+xml`) will eventually make the server return 406 – theoamonteiro Jun 29 '21 at 22:41
  • This question seems to be related to https://stackoverflow.com/questions/13884141/convention-for-http-response-header-to-notify-clients-of-deprecated-api when this question is actually not limiting itself to headers only. Note further that the deprecation header doesn't fit your needs as it will deprecate the resource itself but not the representation format itself. Note that the `Warning` header will be deprecated soon itself: https://github.com/httpwg/http-core/issues/139 – Roman Vottner Jun 30 '21 at 00:26
  • Thanks @RomanVottner . I do not remember of coming across the [mentioned question](https://stackoverflow.com/q/13884141/6252868). Yeah, I would like to find any and all authoritative ways to convey that only the representation is being deprecated, for the URI I would use `Warning` and `Sunset` headers – theoamonteiro Jul 01 '21 at 15:57

2 Answers2

1

Ultimately, the information that you want to inform the client of is one of API or application policy. There really isn't any standard way to convey this information via HTTP; at least, not today. Unless your clients are savvy, even if you did provide this information, they'd likely ignore it and you're back to 406 or 415.

The best standard way I can think of to negotiate this would require the client to send HEAD first with Accept or Content-Type and then the server responds with OK if allowed or the appropriate 406 or 415. HTTP caching and/or other techniques can be used to minimize the number of negotiations, but in the worst case scenario, there is always two requests.

The next best way would arguably be through policy enforced with API versioning. Although the differences in version would only be by representation, all facets are clearly separated. If API version 1.0 supports application/xml it should stay that way - forever. This provides:

  1. Stability and predictability for clients
  2. Should allow you to easily identify clients on the old API (and possibly notify them)
  3. Keeps things simple on the server

There are also few ways to loosely advertise that a particular API version is being deprecated. You could use standard headers such as pragma or warning, or you can use something like api-deprecated-versions: 1.0, 1.1. This approach still requires a client to pay attention to these response headers and may not necessarily indicate when the API will transition from deprecated to completely sunset. Most mature server API policies would have a deprecation period of 6+ months, but this is by no means a hard and fast rule; you'd have to establish that will your clients. What this approach can do is enable telemetry owned by clients to detect that an API (and/or version) they are using is deprecated. This should alert client developers to determine the next course of action; for example, upgrade their client.

Depending on your versioning semantics, if they even exist, you likely can achieve a similar albeit more optimal approach using OPTIONS. There isn't an Allow-Content-Type complement to Allow, but you could certainly define a custom one. You might also simply report api-supported-versions and api-deprecated-versions this way. This would enable tooling and clients to select or detect an appropriate endpoint and/or media type. A client might use this approach each time its application starts up to detect and record whether the endpoint they are using is still up-to-date.

A final suggestion could be to advertise this information by way of an OpenAPI (formerly Swagger) document. Such a document would indicate the available URLs, parameters, and media types. A client could request the appropriate document to determine whether their API and expected media type are supported.

Hopefully that gives you a few ideas. First, you need to define a policy and decide how that will be conveyed. You'll then need to educate your clients on how to take advantage of that information and capability. If they opt not to honor that information, then caveat emptor - they'll just get 406, 415, or some other appropriate error response.

Chris Martinez
  • 3,185
  • 12
  • 28
  • I know that 406 or 415 are inevitable. I just do not want that it blows up on the client without any warning. A client hardly would try to renegotiate the content because of a deprecation (I would not expect them to do it even in face of 406 or 415). I am sadly inclined to do it out-of-band, via e-mail, to all client maintainers – theoamonteiro Jun 29 '21 at 23:06
  • 1
    @theoamonteiro agreed. Even if you had something in place, you're still bound to have some clients that don't pay attention to the information provided. If you don't have another established communication medium, email may be the only other alternative. You might be able to use telemetry and only email clients that would be affected. Things don't have to be mutually exclusive either - do both. Providing some level of transport information should reduce or eliminate the need for email in the future. – Chris Martinez Jun 30 '21 at 14:56
0

There is no authoritative (normative) way of doing this now.

When I first sought to answer this question, it was in my head to suggest adding a header, and lo, that's been proposed.

The Deprecation HTTP Header Field you refer to appears to become that normative way of doing that.

It's also the simplest way to inform a client without the added complexity of other options. This way of informing the client means the client can 100% expect the API to behave the way it always has during the deprecation period, which is often critical.

Often resource, representation, and "representation of resource" can mean the same or different things depending on who you talk to. I would say that pragmatically from the client's perspective, they're the same thing, and so a header is a reasonable method of informing about deprecation.

Kit
  • 20,354
  • 4
  • 60
  • 103
  • Like @VoiceOfUnreason commented the [draft](https://tools.ietf.org/id/draft-dalal-deprecation-header-03.html) is more concerned with resources. I could selectively return the `Deprecated` header if the `Content-Type` returned (or the one sent to indicate the payload) is selecting a deprecated representation, but I am not so sure if this too much of a unexpected behavior. – theoamonteiro Jun 29 '21 at 22:49
  • Fair enough. I think it's key to not change the current behavior until you must change it (unless that behavior is additive like a header). – Kit Jun 30 '21 at 13:07