ASP.NET API versioning

六眼飞鱼酱① 提交于 2019-11-30 10:24:52

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