Q1: So this article says attribute routing is more favourable than conventional routing for api versioning. It\'s not clear to me the reasons behind such claim because to me
The document specifically states "makes it easy" for API versioning, not "makes it easier" or "is preferred".
I don't agree that convention-based routes are necessarily "hard to support" (provided you understand how routing works). But if you are not using a convention that is shared across multiple controllers in your project, it is far less code to maintain if you use attribute routing. Namely, you don't have to specify the controller and action to use on every route in the code since the RouteAttribute
knows the action/controller it is paired with natively.
But as the document points out, putting all of your routes in one place does also have its merits. If your API is such that you can use conventions that apply to multiple/all controllers, then setting a single convention is easier to maintain than multiple route attributes.
For those conventions that might be "hard to support" with the built-in MapRoute
method, you can extend convention-based routing as necessary using your own extension methods and even inherit the RouteBase
class to define them however you like.
Ordering is an issue with attribute routing. In fact, attribute routing makes it more difficult to see what order your routes are registered in. Not all routes are order-sensitive, so it is not an issue much of the time.
However, when you do have an ordering problem with attribute routing, it is much more subtle than when using convention-based routing. Attributes do not guarantee any order when Reflection retrieves them. Therefore, the default ordering is unknown regardless of what order you have specified them on your controller actions.
Fixing ordering on attribute routing can be easy. Simply specify the Order
property of the attribute (lower values are evaluated before higher values).
That said, there is no way to specify order between different controllers, so it could end up biting you. If that happens, the only built-in alternative is convention-based routing.
I can't give a concrete example of where you can use attribute routing where you can't use convention-based routing (and AFAIK, there isn't one). An example of using convention-based routing in a way that is not supported by attribute routing is to make data-driven CMS routes.
Attribute routing supports a subset of the functionality that convention-based routing supports. It is not more advanced technologically than convention-based routing. Convention-based routing gives you the ability to directly specify your own RouteBase
(or Route
) subclass, which allows you to do many things that you cannot do with the built-in attribute routing, such as make routes that are based on subdomains, query string values, form post values, or cookies. You can even make extension methods that generate routes based on conventions in advanced scenarios.
Attribute routing cannot be extended this way without resorting to Reflection because many of the types it uses are marked internal.
But there are 3 compelling reasons you might consider using attribute routing instead of convention-based routing, depending on your project:
The thing to take away from this is: Use the type of routing that will be easiest to maintain in your project. If you have lots of similar patterns, use convention-based routing. If your URLs are inconsistent or irregular across the project or you simply like to see your URLs in the same context as your action methods when you work, consider attribute routing, but keep in mind that convention-based routing is another option.
NOTE: Most of the examples I have linked to are for MVC, not Web API. Routing is very similar (in fact, most of the code classes are shared) between the two frameworks. The same concepts can be used in both MVC and Web API as far as attribute/convention-based routing goes, but do be aware that you need to target the
System.Web.Http
namespace rather than theSystem.Web.Mvc
namespace if you are using Web API and you want to take advantage of those examples.