Sunday, February 26, 2012

ASP.NET MVC 4 (Part 1 - Web API)

Since ASP.NET MVC was launched it became my favorite framework for developing web applications. I believe that Microsoft pushed all the right buttons with it: really well conceived, extensible, modular and testable, with every iteration of ASP.NET MVC bringing lots of great improvements.

Now, MVC4 is in beta, and as before many new features have been introduced. The official whitepaper with the release notes may be read here.

One of the new features is called "ASP.NET Web API" which is, according to Microsoft description:

"(...) a new framework for creating HTTP services that can reach a broad range of clients including browsers and mobile devices. ASP.NET Web API is also an ideal platform for building RESTful services."

This description is not that explicit so I'll just "borrow" the one that Scott Guthrie posted:

(...)
The last few years have seen the rise of Web APIs - services exposed over plain HTTP rather than through a more formal service contract (like SOAP or WS*).  Exposing services this way can make it easier to integrate functionality with a broad variety of device and client platforms, as well as create richer HTML experiences using JavaScript from within the browser.  Most large sites on the web now expose Web APIs (some examples: Facebook, Twitter, LinkedIn, Netflix, etc), and the usage of them is going to accelerate even more in the years ahead as connected devices proliferate and users demand richer user experiences.

Our new ASP.NET Web API support enables you to easily create powerful Web APIs that can be accessed from a broad range of clients (ranging from browsers using JavaScript, to native apps on any mobile/client platform).  It provides the following support:
  • Modern HTTP programming model: Directly access and manipulate HTTP requests and responses in your Web APIs using a clean, strongly typed HTTP object model.  In addition to supporting this HTTP programming model on the server, we also support the same programming model on the client with the new HttpClient API that can be used to call Web APIs from any .NET application.
  • Content negotiation: Web API has built-in support for content negotiation – which enables the client and server to work together to determine the right format for data being returned from an API.  We provide default support for JSON, XML and Form URL-encoded formats, and you can extend this support by adding your own formatters, or even replace the default content negotiation strategy with one of your own.
  • Query composition: Web API enables you to easily support querying via the OData URL conventions.  When you return a type of IQueryable<T> from your Web API, the framework will automatically provide OData query support over it – making it easy to implement paging and sorting.
(...)
Note: I've removed the remaining bullets as they're "just" related with leveraging the existing ASP.NET MVC framework (attributes, model binding, hosting, etc).

Let's analyze the above bullets:
  • "HTTP programming model". Roughly this means:
    • if a HTTP GET is sent it is considered that we're fetching information - read
    • HTTP POST - insert
    • HTTP PUT - update
    • HTTP DELETE - delete (duh)
      Also, we leveraging existing HTTP return codes like:
    • 404 - Element not found
    • 200 - Element returned
    • 401 - Unauthorized 
    • (etc)
  • "Content-negotiation". Means that the caller may decide the format of the returning data. So, the API just returns the data and magic is done elsewhere. Forget stuff like returning a JsonResult as we'll just handle and return the model.
  • "Query Composition". Automatically allow the usage of OData syntax to filter the returned data. Really useful for paging and simple filters for example.

So, basically, we're creating an API just thinking on the thing that matters: the model. Everything else is taken care of, while being as standard as it gets.


Before showing an example remember that Web API is not the silver bullet for every API requirements out there. But, if one needs a simple model-centric, CRUD liked API, ASP.NET Web API is a really nice new feature (although it existed previously as a standalone library named WCF Web API)
  
Anyway, let's see this in action.
 
Create a new project (in this case I'm using Visual Studio 2010 and .NET 4.0) and choose ASP.NET MVC 4 Web Application. Name the project as you please.



Choose the Web API Project Template and press "OK".



A new project will be created with an example Web API and an accompanying web page. Run the project. The expected output is:


Well, isn't it nice? According to the description there's an included "ValuesController" which is a Web API. Let's confirm this. Opening the file ValuesController.cs we have:
public class ValuesController : ApiController
{
    // GET /api/values
    public IEnumerable Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET /api/values/5
    public string Get(int id)
    {
        return "value";
    }

    // POST /api/values
    public void Post(string value)
    {
    }

    // PUT /api/values/5
    public void Put(int id, string value)
    {
    }

    // DELETE /api/values/5
    public void Delete(int id)
    {
    }
}
There are 3 interesting things with this class:
  1. The base class is "ApiController" (opposed to the familiar "Controller" class)
  2. The return type of the actions is not an ActionResult
  3. The URL for the actions (as show in the corresponding comments) doesn't include the Action name and has an "api" prefix.Ex: /api/values/5

Let's add "/api/values" the url of our default page in the browser. Should be something like:   http://localhost:52707/api/values (obviously the port may differ).

In Firefox I get the following result:

A XML file was returned. We don't have any specific XML code in our methods, so this was done "automagically". And why XML and not another format (like JSON)?

To answer that let's fire up Fiddler to see the HTTP request that we've issued.


We can see that it was an HTTP GET action, and that the expected result is XML. Therefore we're informing the server that we expect a XML response.

Let's confirm this by changing the previous request.

Drag&Drop the session  to the "Request Builder" tab. 



Now we have a valid HTTP request that we can modify and re-execute at will. The first thing we'll do is remove the "accept" attribute. The request headers will thus become:

Host: localhost:52707
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

After executing, the new session result should show:


So, the response is now a JSON object (which is the default format for the Web API), as we no longer informed the server that our expected content type was XML.


Just to wrap this first post on the subject let's try a different HTTP action. We'll open the previous request in "Request Builder" inside Fiddler and change the action from "GET" to "POST".


Press execute. The action that is called is now "Post".


The method names map the corresponding HTTP Actions. Also, all the MVC goodies like ActionFilters, IoC, model binding may be used.


This is just the tip of the iceberg and I advise you to look at Getting Started with ASP.NET Web API, as it contains many articles and videos on the subject.

No comments:

Post a Comment