ASP.NET API versioning

只谈情不闲聊 提交于 2019-12-30 03:26:12

问题


I'm new to ASP.NET but I'm looking to implement some versioning for a new API I'm about to start.

I'm not even sure if what I'm looking for is possible but I'm after a very clean version method using a header variable.

Ideally I want to be able to have a versions folder within the code structure and different folders containing the different API versions within that. Each version folder would contain a full copy of the core API code so I'd know there would never be any conflicts etc. I know this would inflate the code but it's worth to keep it very clean and there would only be over 2-3 versions of the API active.

I've found many header samples on the Internet but they all require the classes to be in different namespaces and if I'm doing a complete copy of the code then it's not practical to have to rename all the classes each time they are copied.

Is what I'm trying to do possible? Or is there a cleaner solution when dealing with multiple classes?


回答1:


There are four basic approaches to version the RESTful way -

  1. URI Path This approach takes the following form:

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

  2. URI Parameter This approach takes the following form:

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

  3. Content Negotiation This is done in the HTTP header.

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

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

    x-taskManagerApp-version: 2

I personally like 1st approach. You can read Mike Wasson's ASP.NET Web API: Using Namespaces to Version Web APIs.

Many people have modified Mike Wasson's Original Source. I like the one used in ASP.NET Web API 2 book by Jamie Kurtz, Brian Wortman.

Since it has too many moving pieces, I created a sample project at 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;
    }
}

Usage

You just place RoutePrefix on a controller, and you are 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;
    }
}


来源:https://stackoverflow.com/questions/42371582/asp-net-api-versioning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!