You can read my previous article "Web API Self-Hosting Using Windows Service: Part 1".
Web API is the buzz in the market these days for providing Rest-based APIs. After its first release, further versions have been released, with version 2 being the one with some of the major changes. One of the very good feature introduced was the use of Attribute-based routing of the Web API requests. There were other feature also, but this feature is very big and useful in itself and our discussion will be for this only, in this article. Also, this article has its reference from a great write-up on this feature by Mike Wasson, here, that explains these features.
If you have worked with the initial version Web API, you must be aware of the concept of routing templates for the API controllers. But in its version 2, instead of defining routing templates in WebApiConfig.cs, we can define these templates at the method level, in other words on the methods of the Web API controllers. This is possible using the use of the Route and RoutePrefix attributes, added to the Web API 2. This does not mean we cannot use the routing template with the convention of the first release of the Web API along with this. Both can be used side by side. So let's discuss these.
Initial Code setup
- Create a new MVC web application, with Web API template.
- Add a reference to the Web API 2 libraries, using the Nuget package.
- Add the Postman Google Chrome extension (instead of making any HTML or MVC page, we will be using this extension, to make the test requests to the Web API).
- In our default values controller added, clear all the methods, add an Employee class and a method to return a list of employees. So our API controller will look like the following:
Next, open the WebApiConfig.cs file, remove the default routing templates and simply add config.MapHttpAttributeRoutes() to enable the attribute-based routing.
Run the application. As the application is started, it will also cause hosting of the Web API on the same development server. Now start the Postman extension and add the Web API URL with the method name, to which we want to make REST based calls. Click Send and see the results we receive:
This is the result that was expected.
Route Prefix in Web API
Now, suppose we add another method to it with Route attribute as FindEmployee and we need both of the methods to have a common prefix in the API request URL, say Employee. So instead of adding this as a prefix to the Route attribute of both these methods, we add a common attribute at the class level, called RoutePrefix and set its value to the required prefix, in other words Employee. So our code now changes to:
We can now make a request to both of the controller methods with the same prefix Employee. See the requests below:
Override Route Prefix
Next we have a situation where we do not something our second method to use the same prefix as the first method. One solution could be to use a separate API controller and add the method to it. But this is not a good solution since it may require adding more methods in the future that do not use this prefix. To do this, we have the option to prefix the Route attribute value with a tilde (~) sign at the method level, for which we do not want to have the common prefix. So we add the tilde sign to the second method and make a direct call to the method. See the code below:
Now let's send the request with the changed url's and see the results.
Passing parameters in GET request
Now, let's see how to send parameters to the request URL. For this, we will be required to change the Route template and add a placeholder to it, that will be replaced by the parameter from the GET request.
Now, let's send the request and debug the code:
Bingo, we get the parameter in the code. We can also have a template, where the parameter placeholder is between the URLs. So we can define the Route template something like:
- [Route("FindEmployee/{eid}/Test")]
Let's change our URL and send the request again.
That looks great. This means we can name our URLs differently and hide the actual method names from the client code.
Constraints on URL parameters
We can even restrict the template placeholder to the type of parameter it can have. For example, we can restrict that the request will be only served if the eid is greater than 10. Otherwise the request will not work. For this, we will apply multiple constraints in the same request:
- Type of the parameter eid must be an integer.
- eid should be greater than 10.
Let's see how to do this.
Simply specify the type along with the placeholder, separated by a colon(:). Now try to send the request with a value less than 10 and we get the 404 error.
Change the value to greater than equal to 10 and it starts working again.
Optional and Default parameters
I was really about to end the discussion until I learned of another great feature, using the optional parameters. But in this case, it becomes necessary to provide a default value to that parameter, in the method definition itself. For using optional parameters, we use the question mark(?) symbol to denote that it is an optional parameter. Let's see how to have optional parameters:
So these were some of the great sub-features of the Route and RoutePrefix feature in Web API2. Let's summarize the features we discussed:
- We have the Route attribute at the method level, to define routing templates.
- We can define a common prefix for all the methods of the API controller, using RoutePrefix attribute.
- We can override the RoutePrefix on a method, using the tilde(~) sign.
- We can easily define parameterized templates in the attribute based routing.
- We can have parameters defined in-between the API request URLs.
- We can add certain constraints on the URL parameters, in other words their type or the values they can have, within the template itself.
- We can also have optional parameters in the methods, but with the condition that they must have a default value assigned to them.
So this was about the use of the Route and RoutePrefix attributes in Web API 2. Sample code is attached with this discussion. I hope you enjoyed reading it. Happy coding...!!!