ASP.NET API Versioning

I am new to ASP.NET, but I want to implement some version control for the new API that I am about to start.

I'm not even sure that what I'm looking for is possible, but I am using a very clean version using a header variable.

Ideally, I want to have a version folder in the code structure and different folders containing different versions of the API. Each version folder will contain a full copy of the main API code, so I would know that there will never be conflicts. I know that this will inflate the code, but it's worth keeping it very clean and there will only be more than 2-3 versions of the API.

I found many sample headers on the Internet, but they all require the classes to be in different namespaces, and if I make a full copy of the code, then it is not practical to rename all the classes every time they are copied.

Am I trying to do this? Or is there a cleaner solution when working with multiple classes?

+5
source share
1 answer

There are four main approaches to the RESTful version -

  • URI path This approach takes the following form:

    http: // api / v2 / Tasks / {TaskId}

  • URI parameter This approach is as follows:

    http: // api / Tasks / {TaskId}? v = 2

  • Content negotiation This is done in the HTTP header.

    Content Type: application / vnd.taskManagerApp.v2.param.json

  • Request Header This is also done in the HTTP header.

    x-taskManagerApp version: 2

I personally like the 1st approach. You can read the Mike Wasson ASP.NET Web API: Using Namespaces for Version Web Interfaces .

Many people modified the original source of Mike Woss. I like the one used in the ASP.NET Web API 2 by Jamie Kurtz, Brian Wortman .

Since it has too many moving elements, I created a sample project on GitHub .

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{version}/{controller}", defaults: new { version = "v2" } ); config.Routes.MapHttpRoute( name: "DefaultApiWithId", routeTemplate: "api/{version}/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); 

Then you add ApiVersionConstraint

 public class ApiVersionConstraint : IHttpRouteConstraint { public ApiVersionConstraint(string allowedVersion) { AllowedVersion = allowedVersion.ToLowerInvariant(); } public string AllowedVersion { get; private set; } public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection) { object value; if (values.TryGetValue(parameterName, out value) && value != null) { return AllowedVersion.Equals(value.ToString().ToLowerInvariant()); } return false; } } 

Using

You just put RoutePrefix on the controller and you're done.

 [RoutePrefix("api/{apiVersion:apiVersionConstraint(v1)}/values")] public class ValuesController : ApiController { // GET api/v1/values [Route("")] public IEnumerable<string> Get() { return new string[] { "v1-value1", "v1-value2" }; } // GET api/v1/values/5 [Route("{id}")] public string Get(int id) { return "v1-value-" + id; } } 
+5
source

Source: https://habr.com/ru/post/1264524/


All Articles