Last year, the attribute-based routing was rolled into the core of ASP.NET Web API routing (http://weblogs.asp.net/scottgu/archive/2013/04/19/asp-net-web-api-cors-support-and-attribute-based-routing-improvements.aspx).
I suppose the addition implies it is somehow better than the standard imperative routing approach in app start, but apart from dev preference (which is not my concern here), what are the concrete benefits and drawbacks of the two approaches?
UPDATE: I should clarify that "it is somehow better than the" would be better said as: "it adds value over the". I mean, they would only add it if they thought it was valuable. So my question is really what are the pros/cons between the two approaches (beyond simple preference).
I wouldn't think of it as better just a different way of solving the same problem. Additions to any framework can often simply present an alternative way of doing something. It depends on how opinionated the framework designers wish to be. Typically Microsoft has always aired on the side of being somewhat un-opinionated to the point of developer confusion. But they are getting better though.
The primary benefit I see with attribute based routing, and I appreciate this may be subjective is that it's more explicit in that it brings the definition of the route closer to the target code i.e the controller action.
Given that we as developers already have enough information to wrangle in our heads when reading code, this proximity of the route definition to the executed code can only help in my opinion.
Attribute routing is more DRY. For instance:
[RoutePrefix("{controller}")]
[Route("{reviewId:int}/{action=Show}")]
public class ReviewsController : Controller {
public ActionResult Show(int reviewId) {
throw new NotImplementedException();
}
public ActionResult Edit(int reviewId) {
throw new NotImplementedException();
}
[Route("foo")]
public ActionResult Foo() {
throw new NotImplementedException();
}
}
The routes created for the above controller are:
routes.MapRoute(null, "{controller}/foo",
new { controller = "Reviews", action = "Foo" });
routes.MapRoute(null, "{controller}/{reviewId}/{action}",
new { controller = "Reviews", action = "Show" },
new { reviewId = new IntRouteConstraint() });
Note that:
In imperative routing makes it hard to support nested URI patterns. May times resource can contain child resource like Customer can have orders, In this case URL would be /customers/1/orders
This type of URI is difficult to create using imperative routing. Although it can be done, the results don't scale well if you have many controllers or resource types.
With attribute routing, it's trivial to define a route for this URI. You simply add an attribute to the controller action.
[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
It also solves other problems like ,
API versioning:
"/api/v1/products"
would be routed to a different controller than "/api/v2/products"
.
/api/v1/products
/api/v2/products
Overloaded URI segments In this example, "1" is an order number, but "pending" maps to a collection.
/orders/1
/orders/pending
Mulitple parameter types: In this example, "1" is an order number, but "2013/06/16" specifies a date.
/orders/1
/orders/2013/06/16
Source: https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With