MVC4 and Web Api– make an Api the way you always wanted–Part 1

Update: Part 2 of this series is available here.

ASP.NET MVC is a huge success as framework and just recently, ASP.NET MVC4 Beta was released. While there are many changes in this release, I want to specifically focus on the WebApi portion of this.

In previous flavours of MVC, many people wanted to develop REST Api’s and didn’t really want to use WCF for this purpose. The team at Microsoft was progressing along with a library called WcfWebApi. This library used a very WCF’esque way of defining an Api. This mean defining an interface and decorating the interface with the appropriate WCF attributes to constitute your Api endpoints.

However, a lot of people don’t like to use a WCF style of programming, and are really comfortable in the MVC world. Especially when you can construct similar REST endpoints in MVC with extreme ease. This is exactly what a lot of people who wanted a REST Api did. They simply used ASP.NET MVC to define a route and handled the payload themselves via standard MVC controllers.

What the WcfWebApi did quite well though was things like content negotiation (do you want XML or json?), auto help generation, message/payload inspection, transformation, parameter population and a lot of other things.

Microsoft have recognised all this and decided to mix it all together. Take the good bits of WcfWebApi and the Api development approach of MVC, and created an Api framework to easily expose your REST endpoints and retain the MVC ease of development. This is the WebApi and it supersedes the WcfWebApi (which will not continue to be developed).

So how do you make a REST sandwich now?

Well, best to start with the code.

Firstly, lets define a route for our REST Api.

In the Global.asax, we may have something like this:

public static void RegisterApis(HttpConfiguration config)
{
    config.MessageHandlers.Add(new ApiUsageLogger());

    config.Routes.MapHttpRoute("contacts-route", "contacts", new { controller = "contacts" });
}

Ignore the MessageHandler line for now, we will get back to that in a later post.

You can see we are defining/mapping a Http route. The first parameter is the unique route name, second is the route template to use for processing these route requests. This means that when I get a request like http://MyHost/Contacts, this route will get a match. The third parameter  the default properties. In this case, I am simply stating that the controller to use is the ContactsController. This is shown below.

public class ContactsController : ApiController
{
    public List<ContactSummary> GetContacts()
    {
        // do stuff....            
    }
}

You can see that we have a class that inherits from a new ApiController class. We have a simple controller action that returns a list of ContactSummary objects.

This is (while overly simplistic) a fully fledged REST Api that supports content negotiation and as such will respond with json or XML if it is requested by the client.

The WebApi fully supports your typical Http verbs such as GET, PUT, POST, DELETE etc… and in the example above, the fact that I have an ApiController action method prefixed with a ‘Get’ means it will support the GET verb. If I had a method prefixed with ‘Post’ then that action method, by convention, would support the POST verb. You can optionally decorate the methods with [System.Web.Http.HttpGet], [System.Web.Http.HttpPost] attributes to achieve the same effect.

And OData as well?

Want to support OData? Then simply return an IQueryable<T>. Your Web Api will support querying via the OData URL conventions.

So how do I access this as a consumer?

Accessing your shiny new WebApi can now be done via the HttpClient class which really emphasises everything asynchronous, and easily supports the popular Http verbs GET, PUT, POST, DELETE. Let’s take a look.

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var responseMsg = client.GetAsync("http://SomeHost/Contacts").Result;

The responseMsg variable will contain a list of contacts as shown the in Api method described earlier. You can see we are requesting the data in JSON format. This could also be XML by using:

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var responseMsg = client.GetAsync("http://SomeHost/Contacts").Result;

The Http client has methods for using http verbs explicitly. Namely, GetAsync, PutAsync, PostAsync and DeleteAsync.

Summary

Microsoft have recognised the value of the MVC programming model and incorporated the best of WcfWebApi into MVC for a really nice way of exposing your Api. You get a lot of features for free making great Api’s a hell of a lot easier.

You can get further information on the overall MVC4 release from this post by Jon Galloway.

In the next part to this post, I will explore how you can do model binding, dependency injection, and insert custom handlers into the MVC/Api processing pipeline.

1 Comment

Comments have been disabled for this content.