Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

API versioning with api-supported-versions header #951

Unanswered
jopmiddelkamp asked this question in Q&A
Discussion options

I'm curious if I'm doing something wrong with versioning my API.

Currently I've set up this:

services.AddApiVersioning(opt =>
{
 opt.AssumeDefaultVersionWhenUnspecified = false;
 opt.DefaultApiVersion = new ApiVersion(1, 0);
 opt.ReportApiVersions = true;
 opt.ApiVersionReader = new UrlSegmentApiVersionReader();
})

With these endpoints:

[ApiController]
[Route("/v{version:apiVersion}/users")]
[ApiVersion("1.0")]
[Authorize]
public class UserController : ControllerBase
{
 [HttpGet]
 [Route("{publicKey}")]
 public async Task<IActionResult> FindUser(string publicKey)
 {
 ...
 return Ok(result);
 }
 [HttpPut]
 [Route("{userIdValue}")]
 [Obsolete("Please use the endpoint in V2.")]
 public async Task<IActionResult> UpdateUser(string userIdValue, UpdateUserRequestDto request)
 {
 ...
 return Ok(result);
 }
 [HttpPut]
 [Route("{userIdValue}")]
 [ApiVersion("2.0")]
 public async Task<IActionResult> UpdateUserV2(string userIdValue, UpdateUserRequestV2Dto request)
 {
 ...
 return Ok(result);
 }
}

So now I've got these endpoints showing up correctly in Swagger:

GET -> /v1/user/{publicKey}
PUT -> /v1/user (deprecated)
PUT -> /v2/user

Only when I call the endpoint to get the user, which only has a v1, I get the response api-supported-versions: 1.0, 2.0 which should not happen right? Should it not only show 1.0 here?

Versioning the entire api makes no sense to me but versioning endpoint does. Otherwise with every breaking change the entire api endpoint gets upped 1 version. Even if those endpoints didn't change. Then I also need to make a lot of controller forwards to the legacy controller. Or am I missing something here.

You must be logged in to vote

Replies: 1 comment

Comment options

There is a conflation between the meaning of API with respect to an endpoint. While it's true that a single endpoint can be an API, it's not all that practical. Most APIs are a collection of endpoints. For example, GET /order/{id} and POST /order might be called the Orders API.

Collation is performed by the logical name of the API; not the route template. Route templates cannot safely be collated. For example, order/{id} and order/{id:int} are semantically equivalent, but they aren't the same. API Versioning makes no attempt to understand route templates. Furthermore, should order/{id}/items be part of the Orders API or some other API? Only the author knows that. When you version using the controllers, the name of the controller is the logically name of the API and how versions are collated; in your case, User. Collation only occurs by name. In addition to not considering route template, it doesn't consider HTTP method either.

An API and its versions make up a lot more than just an endpoint. An API version cannot not define the entire policy associated with an API. OpenAPI and (the new) sunset policies provide additional context for client that you just can't get from a list of supported and deprecated versions. In this scenario, if GET is requested for 2.0, then 405 is returned. This might seems a mismatch, but the server is communicating the available versions of an API, not just a single endpoint. If the client was bound to 1.0, how would they ever know there was a 2.0 from a GET request as it is no longer supported?

I hope that helps and clarifies a few things.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /