Showing posts with label Web API. Show all posts
Showing posts with label Web API. Show all posts

Monday, 25 June 2012

Using the CachingHandler in ASP.NET Web API


Introduction


[NOTE: Please also see updated post and the new framework called CacheCow
This class has been removed from WebApiContrib code and NO LONGER SUPPORTED]


[Level T3] Caching is an important concept in HTTP and comprises a sizeable chunk of the spec. ASP.NET Web API exposes full goodness of the HTTP spec and caching can be implemented as a message handler explained in Part 6 and 7. I have implemented a CachingHandler and contributed the code to the WebApiContrib in GitHub.

This post will have two sections: first a primer on HTTP caching and then how to use the handler. This code uses ASP.NET Web API RC and with .NET 4 (VS 2010 or 2012).

Background

NOTE: This topic is fairly advanced and complex. You do not necessarily need to know all this in order to use CachingHandler and are welcomed to skip it but more in-depth knowledge of HTTP could go a long way. 

Caching is a very important feature in the HTTP. RFC 2616 extensively covers this topic in section 13. Review of all the spec is beyond the scope of this post but we will briefly touch on the subject.

First of all let's get this straight: this is not about putting an object in memory as we do with HttpRuntime.Cache. In fact server does not store anything (more on this below), it only tells the client (or mid-stream cache or proxy servers) what can be cached, how long and validates the caching.

Basically, HTTP provides semantics and mechanism for the origin server, client and mid-stream proxy/cache servers to effectively reduce traffic by validating the version of the resource they have against the server and retrieve the resource only if it has changed. This process is usually referred to as cache validation.

In HTTP 1.0, server would return a LastModified header with the resource. A client/user agent could use this value and send it in the If-Modified-Since header in the subsequent GET requests. If the resource was not changed, server would respond with a 304 (Not Modified) otherwise the resource would be sent back with a new LastModified header. This would be also useful in PUT scenarios where a client sends a PUT request to update a resource only if it has not changed: a If-Unmodified-Since header is sent. If the resource has not changed, server fulfils the request and sends a 2xx response (usually 202 Accepted) otherwise a 412 (Precondition Failed) is sent.

For many reasons (including the fact that HTTP dates do not have milliseconds) it was felt that this mechanism was not adequate. In HTTP 1.1, ETag (Entity Tag) was introduced which is an opaque Id in the format of a quoted string that is returned with the resource. ETags can be strong (refer to RFC 2616 for more info) or weak in which case they start with w/ such as w/"12345". ETag works like a version ID for a resource - if two ETags (for the same resource) are equal, it means those two versions of the resource are the same.

ETag for the same resource could be different according to various headers. For example a client can send an Accept-Language header of de-DE or en-GB and server would send different ETags. Server can define this variability for each resource by using Vary header.

Cache validation for GET and PUT requests are similar but instead will use If-Match (for PUT) and If-None-Match (for GET).

Well... complex? Yeah, pretty much and yet I have not covered some other aspects and the edge cases. But don't worry! You will be abstracted from a lot of it if you use the CachingHandler.

Using CachingHandler right out of the box

OK, using the CachingHandler is straightforward especially if you go with the default settings. You can have a look at the CarManager sample in the WebApiContrib project. CarManager.Web sample demonstrate server side setup of the caching and CarManager.CachingClient for making calls to the server and testing various caching scenarios.

All you have to do is to create an ASP.NET Web API project and add the CachingHandler as a delegating handler as we learnt in Part 6:

GlobalConfiguration.Configuration.MessageHandlers.Add(cachingHandler);

And you are done! Now let's try the server with some scenarios. I would suggest that you use the CarManager sample, otherwise create a simple handler and implement GET, PUT and POST on it.

Now let's make some request and look at the response. I would suggest using Fiddler or Chrome's Postman to send requests and view the response.

So if we send a GET request:

GET http://localhost:8031/api/Cars HTTP/1.1
User-Agent: Fiddler
Host: localhost:8031

We get back this response (or similar; some headers removed and body truncated for clarity):

HTTP/1.1 200 OK
ETag: "54e9a75f2dbb4edca672f7a2c4a73dca"
Vary: Accept
Cache-Control: no-transform, must-revalidate, max-age=604800, private
Last-Modified: Thu, 21 Jun 2012 23:35:46 GMT
Content-Type: application/json; charset=utf-8

[{"Id":1,"Make":"Vauxhall","Model":"Astra","BuildYear":1997,"Price":175.0....

So we see the ETag header here along with important caching headers. Now if we make another GET call, we get back the same response but ETag and last modified stays the same.

Generating same ETag is fine (showing our CachingHandler is doing something) but we have not yet seen any caching. That is where client has to do some work to do. It has to use If-None-Match with the ETag to conditionally ask for the resource: if it matches server, it will get back 304 but if not, server will return the new resource:
GET http://localhost:8031/api/Cars HTTP/1.1
User-Agent: Fiddler
Host: localhost:8031
If-None-Match: "54e9a75f2dbb4edca672f7a2c4a73dca"
Here we get back 304 (Not modified) as expected:
HTTP/1.1 304 Not Modified
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
ETag: "54e9a75f2dbb4edca672f7a2c4a73dca"
Server: Microsoft-IIS/8.0
Date: Sun, 24 Jun 2012 07:34:29 GMT

A typical server that can use CachingHandler

CachingHandler makes a few RESTful assumptions about the server for effective caching. Some of these assumptions can be overridden but generally not recommended. These assumptions are:

  • HTTP verbs (POST/GET/PUT/DELETE for CRUD operations) are used to modify resources - and not RPC-style resources (such as POST /api/Cars/Add). This is the most fundamental assumption.
  • All resources are to be modified through the same HTTP pipeline that implements caching. If a resource modified outside the pipeline, cache state needs to be updated by the same process.
  • Resource are organised in a natural cache-friendly manner: invalidation of related resources can be done with a minimal setup (more details upcoming).

Defining cache state

As we said, this has nothing to do with HttpRuntime.Cache! Unfortunately ASP.NET implementation makes it really confusing between the HTTP cache (where the resource gets cached on the client or midstream cache servers) and server caching (when the rendered output gets cached on the server).

Cache state is a collection of data that helps keep track of each resource along with its last modified date and ETag. It might initially seem that for a resource, there exists a single of such pieces of information. But as we touched upon above, a resource can have different representations each of which needs to be stored separately on the client while they will most likely invalidated together. 

For example, resource /api/disclaimer can exist in multiple languages as such client has to cache each representation separately but when disclaimer changes, all such representations need to be invalidated. That will require a storage of some sort to keep track of all this data. Current implementation comes with an in-memory storage but in a web farm scenario this needs to be a persistent store.

Cache state storage and cache invalidation

So we do not need to store the cache on the server, but we DO need to store ETag and various states on the server. If we only have a single server, this state can be stored in the memory. In a web farm (or even web garden) scenario a persisted store is needed. This store is called Entity Tag Store and is represented by a simple interface:

public interface IEntityTagStore
{
 bool TryGetValue(EntityTagKey key, out TimedEntityTagHeaderValue eTag);
 void AddOrUpdate(EntityTagKey key, TimedEntityTagHeaderValue eTag);
 bool TryRemove(EntityTagKey key);
 int RemoveAllByRoutePattern(string routePattern);
 void Clear();
}

We need to have an implementation of this interface so that the cache management can be abstracted away from controllers and instead done in the DelegatingHandlers.

Introducing some concepts (you may skip and come back to it later)

This store will keep track of the Etag (and related state stored in TimedEntityTagHeaderValue) based on an Entity Tag key which is calculated based on the resource URI and content of the important headers (which their list will be on the Vary header). In-Memory implementation for a single server is provided out of the box with CachingHandler - I would be creating a SQL-Server implementation of it very soon; watch this space.

It is important to note that change in the resource will most likely invalidate all forms of the resource so all permutations of important headers will be invalidated. So invalidation is usually performed at the resource level. Sometimes several related resources can be represented as a RoutePattern. By default, URI of a resource is its RoutePattern.

Also in some cases, change in a resource will invalidate linked resources. For example, a POST to /api/cars to add a car will invalidate /api/cars/fastest and /api/cars/mostExpensive. In this case, "/api/cars/*" can be defined as the linked RoutePattern (since /api/cars does not qualify for /api/cars/*).

Some assumptions in CachingHandler

  1. Re-emphasising that resource can only change through the HTTP API (using PUT, POST and DELETE verbs). If resources are to be changed outside the API, it is responsibility of the application to use IEntityTageStore to invalidate the cache for those resources.
  2. If no Vary header is defined by the application, CachingHandler creates weak ETags.
  3. Change in the resource will invalidates all forms of the resources (all permutations of important header values)

CarManager sample

I have considered a pretty complex and interrelated routing and caching requirement for the sample to display what is possible. Resources available are:

  1. /api/Car/{id}: GET, PUT and DELETE
  2. /api/Cars: GET and POST
  3. /api/Cars/MostExpensive: GET
  4. /api/Cars/Fastest: GET
So creating a car would invalidate cache for 2, 3 and 4. Updating car with id=1 invalidates 2,3 and 4 in addition to the car itself at /api/Car/1. Deleting a car will invalidate 2, 3 and 4.

The client sample (CarManager.CachingClinet) displays how to call the server with headers to validate the cache.

Configuring CachingHandler

Best place to start is the CarManager.Web sample to give an idea on how various setup can be used to configure complex caching requirements. Basically the points below can be used to configure the CachingHandler

Constructor

A list of request header names can be passed that will define the vary headers. If no vary header is passed, system only generates weak ETags. Also optionally an implementation of IEntityTagStore otherwise by default InMemoryEntityTagStore will be used.


EntityTagKeyGenerator

This is an opportunity to provide linked resource for a resource.

 Other customisation points

CachingHandler provides properties in the form of functions with default implementation that can be changed  to override the default behaviour which we will cover in the upcoming post on "Extending CachingHandler".


Conclusion

CachingHandler is a server-side DelegatingHandler which can be used to abstract away caching from individual ApiControllers so that controller logic can be coded without having to worry about caching. 

The  code is hosted on GitHub (currently sitting at my fork waiting to be merged merged!) and comes with both a client and server sample - CarManager.Web and CarManager.CachingClient.

Thursday, 14 June 2012

ASP NET Web API Series - Part 9: MediaTypeFormatter on the client


Introduction

[Level T3] In part 5 we talked about MediaTypeFormatter on the server. We have another side of the story - perhaps not as big - on the client. MediaTypeFormatters will helps us converting our ViewModels/DTOs to and from HTTP content. HttpClient exposes full goodness of server side formatting as we have seen in part5. This post is going to be short and simple - especially if you have read the server-side post.

Why should I care?

You should care if you want to do anything useful consuming an HTTP API from a .NET client - and not Javascript. 

As we discussed on the server-side post, MediaTypeFormatter marries the world of HTTP (headers and body) to the world of .NET (strongly-typed objects). It will be very likely that you will be sending some strongly typed objects across the wire and expecting the same back. MediaTypeFormatter will help you achieve that.

ObjectContent and ObjectContent<T>

ASP.NET Web API abstracts the HTTP message's body and its body-related headers as HttpContent class - this applies to both request and response. So what are body-related headers? Here is a list:
  • Allow
  • Content-Disposition
  • Content-Encoding
  • Content-Language
  • Content-Length
  • Content-Location
  • Content-MD5
  • Content-Range
  • Content-Type
  • Expires
  • Last-Modified
As we have highlighted, Content-Type is the key header here - as for the media type formatting. These are in fact the same headers that can appear in each part of a Multipart message. As we covered briefly before, in a multi-part message, each part gets its own share of the body and body-related headers.

While HttpContent generally abstracts HTTP body as a stream, ObjectContent which inherits from HttpContent abstracts it as a strongly typed object - especially the generic type ObjectContent<T>

Creating an ObjectContent<T>

ObjectContent<T> has two constructors:

public ObjectContent(T value, MediaTypeFormatter formatter) : this(value, formatter, null)
{
}

public ObjectContent(T value, MediaTypeFormatter formatter, string mediaType) : base(typeof(T), value, formatter, mediaType)
{
}

We are supposed to pass the value of generic type T and pass the actual MediaTypeFormatter we want to format the content. The content then can be used to be sent to the server, for example in a post:

var content = new ObjectContent<foo>(new Foo(), new JsonMediaTypeFormatter);
var httpClient = new HttpClient();
httpClient.PostAsync(url, content);

Since it is the client who initiates the HTTP call, it would know what format to send the request body in. So the content-negotiation does not apply here. Having said that, I would have liked to be able to POST a request without having to decide on a MediaTypeFormatter and let Web API to choose a default formatter for me. I have not been able to find this in the framework yet.

Choosing a default media type formatter is not that hard in fact. All we have to do is to create a new MediaTypeFormatterCollection and then choose the JsonFormatter or XmlFormatter property.

MediaTypeFormatterCollection

ASP.NET Web API comes with a non-generic collection for MediaTypeFormatter. Unlike most collections which are a bag/list of their items, MediaTypeFormatterCollection has some knowledge and understanding of the formatters.

For starter, constructor of this collection creates the collection with these three default formatters:

public MediaTypeFormatterCollection() : this(CreateDefaultFormatters())
{
}

private static IEnumerable<MediaTypeFormatter> CreateDefaultFormatters()
{
    return new MediaTypeFormatter[] { new JsonMediaTypeFormatter(), 
          new XmlMediaTypeFormatter(), 
          new FormUrlEncodedMediaTypeFormatter() };
}

Also it has three properties: JsonFormatter, XmlFormatter and FormUrlEncodedFormatter. With using the parameterless constructor, each of these properties will point to one of the formatters constructed. However, if we create our own IEnumerable<MediaTypeFormatter> and pass to constructor, collection will find these formatters and assign the properties. I call these common formatters since they are bread and butter of the web.

Formatting objects into HTTP content (Request)

As we saw earlier, we can directly create an ObjectContent<T> or do that as part of POST/PUT:

client.PostAsync<Foo>(uri, new Foo(),
 new MediaTypeFormatterCollection().JsonFormatter);

This is not really much more complex than that.

Reading object from HTTP content (response)

This is where ASP.NET Web API provides on the client its full media type formatter selection on the server. Normally you would use ReadAsAsync<T> on the HttpResponseMessage. For example:

Foo result = client.GetAsync(uri)
 .Result.Content.ReadAsAsync<Foo>().Result;

As you can see, no media type formatter had to be passed and we used the organic media type formatter selection within the framework. How? Well, parameterless ReadAsAsync<T> is in fact an extension method that creates a new MediaTypeFormatterCollection (as we saw above) and pass as a set of formatters:

public static Task<T> ReadAsAsync<T>(this HttpContent content)
{
    return content.ReadAsAsync<T>(new MediaTypeFormatterCollection());
}

This in turn will call other methods and in the end, FindReader method of the MediaTypeFormatterCollection will be used to select a suitable formatter based on type and Contet-Type header.

Example: using Rotten Tomatoes web API

Rotten Tomatoes is a popular website for movie reviews. So if you are a movies fan like me, and you are into Web API, you might be tempted to expose the search movie search functionality in your application/mashup.

So what you need is an API key. It is free to acquire and you just need a Mashery ID and register for an API key in Rotten Tomatoes here. After you got your api key, you need to append this key as a query string parameter to all your calls.

So let's imagine we want to search films having "matrix" word in them. I have done that and here is the JSON.

Next step is to create classes to represent your JSON. You are welcome to do that by hand but there is a useful online tool there that can do that for you: json2csharp.

So here is what it has generated:

public class ReleaseDates
{
    public string theater { get; set; }
    public string dvd { get; set; }
}

public class Ratings
{
    public string critics_rating { get; set; }
    public int critics_score { get; set; }
    public string audience_rating { get; set; }
    public int audience_score { get; set; }
}

public class Posters
{
    public string thumbnail { get; set; }
    public string profile { get; set; }
    public string detailed { get; set; }
    public string original { get; set; }
}

public class AbridgedCast
{
    public string name { get; set; }
    public string id { get; set; }
    public List<string> characters { get; set; }
}

public class AlternateIds
{
    public string imdb { get; set; }
}

public class Links
{
    public string self { get; set; }
    public string alternate { get; set; }
    public string cast { get; set; }
    public string clips { get; set; }
    public string reviews { get; set; }
    public string similar { get; set; }
}

public class Movy
{
    public string id { get; set; }
    public string title { get; set; }
    public int year { get; set; }
    public string mpaa_rating { get; set; }
    public int runtime { get; set; }
    public string critics_consensus { get; set; }
    public ReleaseDates release_dates { get; set; }
    public Ratings ratings { get; set; }
    public string synopsis { get; set; }
    public Posters posters { get; set; }
    public List<AbridgedCast> abridged_cast { get; set; }
    public AlternateIds alternate_ids { get; set; }
    public Links links { get; set; }
}

public class Links2
{
    public string self { get; set; }
    public string next { get; set; }
}

public class RootObject
{
    public int total { get; set; }
    public List<Movy> movies { get; set; }
    public Links2 links { get; set; }
    public string link_template { get; set; }
}

As you can see, it does a very good job in converting them but there are some naming conventions that you might have to go back and re-visit (In C# we use Pascal-Casing). Also Movy really needs to be Movie but for our purpose it is just fine.

So let's open Visual Studio 2010 and create a new console application project. Then add a code file and paste the codes above in there.

Then in the "Package Manager Console", type

PM> Install-Package System.Net.Http.Formatting
This should add all client libraries you need. Then we just need to write

var httpClient = new HttpClient();
   var rootObject = httpClient.GetAsync("http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=matrix&page_limit=2&page=1&apikey=[YOUR_API_KEY]")
    .Result.Content.ReadAsAsync<RootObject>();

You should have the data correctly deserialised back to your objects. Well, not quite, there is a problem since the API uses legacy content-type "text/javascript" for the JSON instead of  "application/json". With the technique we learnt back in Part 7 and 8, we can create a message handler to change the legacy content type to the correct one and add it to the pipeline:

public class LegacyJsonMediaTypeConverterDelegatingHandler : DelegatingHandler
{
 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
    
  return base.SendAsync(request, cancellationToken)
     
   .ContinueWith(task =>
             {
                 var httpResponseMessage = task.Result;
        if (httpResponseMessage.Content.Headers.ContentType.MediaType == "text/javascript")
         httpResponseMessage.Content.Headers.ContentType.MediaType = "application/json";
                 return httpResponseMessage;
             });
 }
}

Now all we have to do is to add the handler to the pipeline and make the call:

static void Main(string[] args)
{

 var httpClient = new HttpClient(new LegacyJsonMediaTypeConverterDelegatingHandler() { InnerHandler = new HttpClientHandler()});
   
 var rootObject = httpClient.GetAsync("http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=matrix&page_limit=2&page=1&apikey=YOUR_API_KEY")
  .Result.Content.ReadAsAsync<RootObject>();


 Console.Read();
}


Conclusion

ObjectContent<T> is an important class in ASP.NET Web API which abstracts the HTTP content (or a part within a multipart message) which includes its body and body-related headers.

MediaTypeFormatter on the client is as important as on the server. For sending requests, since client is the initiator of the request, it needs to explicitly set the formatter. For processing response data, however, a suitable formatter is selected based on type of the object to be read and content-type.

Tuesday, 5 June 2012

ASP.NET Web API Series - Part 8: MessageHandler on the Client


Introduction

[Level T2] So far we have only covered server-side features while Microsoft's ASP.NET Web API has excellent client-side features. It is true that server-side requires a lot of care and attention but as I have pointed out in the past, implementing REST-style application usually involves a client burden. In this post, we will cover Russian Doll model on the client (for more background have a look at part 6).

Client arsenal in the age of Web API

Before Microsoft HTTP history was re-written in ASP.NET Web API, there were 3 ways to make an HTTP request:

  1. High-level WebClient. While lacked some tuning features, it presented a useful tool capable of HTTP, FTP and file access.
  2. Mid-level HttpWebRequest: This was used most often and presented abstractions at the right level.  
  3. Close-to-the-metal Windows socket. While you could, I cannot think of a reason why you would.

While these could still prove useful, Microsoft has designed and built HttpClient class and it is intended to be used as the main client API in the Web Stack. If you read Mike Wasson's excellent post on Message Handlers you will know why: it has been built using the same abstractions as the server side of Web API. This enables lego-esque pipeline of various message handlers (as we have seen before) each to add a nice little feature to the pipeline.

HttpClient

First of all HttpClient is heavily asynchronous - well that is an understatement, it is purely asynchronous.

Using HttpClient is simple:

var client = new HttpClient();
var asyncTask = client.GetAsync("http://webapibloggers.com");
asyncTask.ContinueWith(task =>
               {
       Thread.Sleep(2000);
                   task.Result.Content.ReadAsStringAsync()
                       .ContinueWith(readTask => Console.WriteLine(readTask.Result));
               });
Console.WriteLine("Waiting ...");
Console.Read();

or even simpler:

string result = client.GetAsync("http://webapibloggers.com")
 .Result.Content.ReadAsStringAsync().Result;

or even simpler:

var result = client
   .GetStringAsync("http://webapibloggers.com").Result;

There is not much magic in using HttpClient. Basically you may use

  • GetAsync: analogous to HTTP GET
  • PostAsync: analogous to HTTP POST
  • PutAsync: analogous to HTTP PUT
  • DeleteAsync: analogous to HTTP DELETE
  • GetStringAsync, GetByteArrayAsync and GetStreamAsync if all you care is the Content
  • SendAsync: general method if you want to have full control on constructing an HttpRequestMessage or want to use other/custom verbs.

Specifying an HttpMessageHandler

When you create an HttpClient using its parameterless constructor, in fact this is what you are doing:

public HttpClient() : this(new HttpClientHandler())
{
}

So basically the default constructor creates an HttpClientHandler to handle the all leg work for passing the request over to the server and then construct an HttpResponseMessage based on the result.

HttpClientHandler in fact uses HttpWebRequest and HttpWebResponse behind the scene (discussion here) but translates the communication to ASP.NET-agnostic model of the Web API, a.k.a. HttpRequestMessage and HttpResponseMessage.

The the other two constructors we can pass an HttpMessageHandler. This message handler has to be the handler that ultimately returns the result - usually from the server over the wire. Well, I said usually since nothing stops us to put a full-fledged HttpServer in there: this means the request and response will not even touch the wire and will run fully in-memory. Pedro Felix shows us how to do this here.

HTTP pipeline on the client


What if we do not want to mess around with all the whole communication pipeline and we just want to use a DelegatingHandler? Well, not so difficult, all we have to do is to create a delegating handler and set its InnerHandler to an HttpClientHandler.

Here we look our minimal scenario where we have delegating handler that outputs Uri into the Trace:

public class LoggingHandler : DelegatingHandler
{
 public LoggingHandler()
 {
   InnerHandler = new HttpClientHandler();
 }

 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
  Trace.WriteLine(request.RequestUri.ToString());
  return base.SendAsync(request, cancellationToken);
 }
}

class Program
{
 static void Main(string[] args)
 {
  var client = new HttpClient(new LoggingHandler());
  var result = client.GetStringAsync("http://webapibloggers.com").Result;
  Console.WriteLine(result);
  Console.Read();
 }
}

We can see the trace output in the Visual Studio output window.

Real-world client message handlers

Admittedly, there are far less implementation of message handlers on the client perhaps since most early adopters of ASP.NET Web API have been server-focused geeks. Yet, there are some implementations out there.

Henrik explains how to build an OAuth message handler and use it to build a twitter client. This sample can be downloaded from here.

I am hoping to build a CachingHandler on the client using ASP.NET Web API. If all goes well, this should be the topic of the next post.

Conclusion

ASP.NET Web API offers the same wealth of HTTP pipeline abstractions (known as Russian Doll model) on the client as on the server. HttpClient is the main tool to make HTTP calls and it - by default - uses HttpClientHandler for all its communications. If you need to provide a delegating handler (or a series of delegating handlers) you can pass it to the constructor while setting the InnerHandler to an instance of HttpClientHandler.

Wednesday, 30 May 2012

For those about to ASP.NET Web API, we salute you

[Level: N]

A new ASP.NET Web API aggregator has been set up at webapibloggers.com - courtesy of @alexzeitler. My humble blog is also one of the many blogs aggregated on this place. It is a nice place to follow up trends and what is happening on the community. You may also follow the twitter account at @webapicontrib.

So if you are about to ASP.NET Web API, we SALUTE you. Have a look in there.

For those about to ASP.NET Web API, we salute you!

Monday, 28 May 2012

ASP.NET Web API Series - Part 7: Real world Message Handlers


Introduction

[Level T2] In the previous post we reviewed Web API's pipeline a.ka. Russian Doll model. In this post we further on what discussed with a few examples built by the community. Also before that, we look on how to use a per-route message handler while keeping all the goodness of controller functionality.

If you have written a real-world handler in ASP.NET Web API, please contact me in the comments below or on Twitter (@aliostad) to be reviewed and added to the post.

Have the cake and eat it at the same time

In the previous post, we talked about the benefits of the per-route message handlers. Henrik's example is an implementation of HttpMessageHandler which will basically needs to do every thing by itself. So the question arises, how can I have the flexibility of the per-route message handlers while benefit from all the luxury of formatting, action invocation, controller mechanisms, etc. In other words, how can I invoke my controller in a per-route case? Well that sounds like have the cake and eat it at the same time.


Well, it turns out it is possible. I managed to get this working, calling my actions using a per-route handler. The trick is that you set up your Russian dolls and last one ending with an HttpControllerDispatcher.

So let's look at an example. Here we have is a humble delegating handler that outputs the request URL to the trace.

public class TraceHandler: DelegatingHandler
{
 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
  Trace.WriteLine(request.RequestUri.ToString());
  return base.SendAsync(request, cancellationToken);
 }
}

Now if we want to set up this DelegatingHandler per-route, we simply create a new HttpControllerDispatcher and set it to the InnerHandler of the TraceHandler:

config.Routes.MapHttpRoute(
 "DefaultApi",
 "api/{controller}/{id}",
 new{ id = RouteParameter.Optional},
 null,
 new TraceHandler(){InnerHandler = new HttpControllerDispatcher(config)});

Creating HttpControllerDispatcher is easy and we just need to pass the HttpConfiguration object (depending on the SelfHost or Web scenario).

So this way we can have our per-route delegating handler running only for that route yet all the controller action binding and formatting intact.

Real-world message handlers

Since the beta version of the Web API was out, community has been building interesting and useful handlers. So I thought instead of me coming up with arbitrary or simple cases, I could introduce the great stuff community has done so far. And that is what I did. The very last one is the introduction of my CachingHandler which deserves a post on its own.

Tracking Web API usage by your customers

Filip Woj shows us how to build a DelegatingHandler to support tracking usage of your API. But not just that, actually all the nitty-gritty of building the infrastructure (repositories, etc) to support it. This can be a very useful feature if you want to monetise your API and need to charge per call or make sure the call is made within the number of calls allowed for the customer.

Radenko tries to solve a similar problem with throttling usage of the API. He uses HttpRuntime.Cache for storing the statistics. As he explains, he will be moving the storage to Membase. Generally use of the cache for storing data is not great since system can remove the data if memory becomes a scarce resource (which happens often on a web server, especially the one needing throttling).

Authentication and security

John Petersen looks into using a delegating handler for token-based authentication. He uses public/private key and RSA for creating tokens (perhaps we could also choose a stronger algorithm since token is small unlike the whole HTTP communication) and creates 3 different handlers: one to make sure the request uses TLS/SSL, other to ensure the IP address of the client is from a white-list and finally the handler to create and verify authentication token.

Antony Scott also takes on the Basic Authentication and explains how to process the authentication header and set the identity of the current thread. There is not a lot of code there, not more than you need displaying how easy it is to do basic authentication if you use all the correct points of the system.

Perhaps the most important implementation of security which also includes use of message handlers, is Dominick Baier's Thinktecture Identity model on github. Dominick explains this in his blog post here and his library supports all major standards.

Other

Mike Wasson explains here how to create HTTP method override delegate in ASP.NET Web API. The idea is that using HTTP methods other that POST and GET might be tricky on some servers. For example, there is a known issue in IIS whereby PUT or DELETE methods will return 404 if you have WebDAV installed on the server. In such cases, by convention client sends a custom HTTP header with the key of X-HTTP-Method-Override containing the alternate method. In this case, the handler will read the header and change the method. It is important to note that binding to the controller and action selection and invocation happens later so this change of method will be effective. 

Caching

HTTP caching is a very important feature in RFC 2616. A whole chapter in the spec is dedicated to it and arguably involves some of the most complex rules in the whole spec. Caching is also one of the tenants of REST and as such plays an important role in the design, architecture and scalability model of the web. In the last few weeks I have been busy building a CachingHandler for the WebApiContrib and currently it is available in my fork of the project. In the next post, I will be going through some of the challenges I was facing and the solutions I came up in writing this complex handler. It was good fun!

Conclusion

Per-route message handlers can be enhanced if we mix delegating handler(s) with HttpControllerDispatcher. In this case, we can have a number of delegating handlers last one ending with the controller dispatcher. This leaves media formatting, controller selection, model binding and action invocation intact while we can have all the flexibility of per-route handlers.

We also reviewed a few useful handlers built by the community and available at the time of writing this post. In the next post, we will cover the CachingHandler.

Saturday, 19 May 2012

ASP.NET Web API Series - Part 6: MessageHandler explained


Introduction

[Level T3] MessageHandler is a new concept in ASP.NET Web API and a very useful tool in separation of concerns in a Web API service. In this article we will review the concept and outline its usefulness with a few simple examples.

Background

IIS as the Windows platform's HTTP server implementation, has always had two concepts: a component that receives HTTP request and responsible for returning a response (endpoint of communication), and another component that sniffs the communication and can quietly read/write from/to the request/response.

In the old times of unmanaged C++ IIS application implementation, we had ISAPI extensions and ISAPI filters. So the first one was responsible for reading request and sending back a response while the other, would be sniffing incoming and outgoing messages and perhaps sneak in/out a few headers or content. Difference also explained here.

In ASP.NET we had the same two familar concepts: HTTP Handlers and HTTP Modules with corresponding IHttpHandler and IHttpModule interfaces, respecitvely. Again here, we had handlers responsible for handling the request and returning a response, while HttpModule would be sitting as a not-so-innocent-bystander and sniff in what goes and chip in when necessary.

To illustrate this further, all Web Forms pages or MVC controllers can be looked as HTTP Handlers (although the interface itself would be implemented much higher in the pipeline but would delegate the responsibility to page or controller action). On the other hand, useful tools such as Glimpse or ELMAH use HTTP module to intercept the errors or routes from the stream of incoming/outgoing request/response. ASP.NET MVC has a concept of ActionFilter which is similar but for the sake of brevity it is better not to delve into it.

ASP.NET Web API continues these two concepts yet combines them into HttpMessageHandler which is the base class for important classes in the stack such as HttpServer, HttpControllerDispatcher and HttpRoutingDispatcher. This class can be implemented as both an equivalent of HTTP module or handler. Yet DelegatingHandler, a subclass of HttpMessageHandler has been specialised into an equivalent of HTTP module. While understanding of HttpMessageHandler is important, it is much more likely that you will only implement DelegatingHandler. As such we cover it in more details.

DelegaingHandler in Web API

DelegatingHandlers are used in the Web API to represent Message Handlers before routing (see below). They are ordered modules in the HTTP pipeline stream each one receiving request, doing some work and pass to the next. On the outbound stream also response is taken, processed passed to the next. However, at any point, a handler can decide to take action and process the request returning the response without passing to the next one. If I need to show this, I would use my very crude drawing techniques:

Request/Response pipeline and Message Handlers in ASP.NET Web API - in a crude way :)


So now let's think about it. We have a stack of message handlers: first handler to receive the request is the last one to be passed the response, vice versa. This is similar to Russian Dolls, each inside the other.

Russian doll model

If you have not seen Russian dolls, well there it is for you:



 The idea is that you you buy just the biggest doll and once you open it, you find a smaller one and if you open that one, you see a smaller... until you get to the last one. 

So let's look at the DelegatingHandler and other classes in the hierarchy:

Class hierarchy of Message Handlers in System.Net.Http.dll

As can be seen, DelegatingHandler is a derived class from HttpMessageHandler and has a property of InnderHandlerThis inner handler in fact is the smaller Russian Doll inside the handler. So as you can imagine all these handlers are chained together using this InnerHandler property.

There is in fact some code in ASP.NET Web API that turns IEnumerable<DelegatingHandler> into a chain of DelegatingHandlers.

How does a DelegatingHandler work?

DelegatingHandler mainly has to implement SendAsync method. This method receives a HttpRequestMessage (and a cancellation token) and must return a Task<HttpResponseMessage>. So you might have expected to see two methods, one for handling request and one for handling response, but they are all combined into one because of the power and beauty of Task<T>.

Basically in a delegating handler, if you need to inspect the request then you would simply do it in the SendAsync. However, if you need to work on the response, you would do it in the continuation of the Task.

So let's see some code. Let's imagine I need to write to the trace all incoming request URLs and add a custom response header identifying that this URL has been written to the trace (a very fictitious case, we will see some real world scenarios in the next post), we can code it very easily:


public class DummyHandler : DelegatingHandler
{
 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
  // work on the request 
  Trace.WriteLine(request.RequestUri.ToString());

  return base.SendAsync(request, cancellationToken)
   .ContinueWith(task =>
                {
      // work on the response
                   var response = task.Result;
        response.Headers.Add("X-Dummy-Header", Guid.NewGuid().ToString());
        return response;
                });
 }
}


Execution of message handlers in Web API pipeline

Until recently, you could only register MessageHandlers globally. ASP.NET team have recently added much awaited per-route message handler support announced only a few weeks ago.

So as explained and illustrated by Henrik in the link above (and also by Kiran Challa in his nice diagram), execution of message handlers depends on whether they are registered globally or per-route. Global message handlers are executed before HttpRoutingDispatcher work while per-route message handlers are executed after it.

Registering a global message handler (DelegatingHandler)

Global message handlers (must be DelegatingHandlers) are a property of the configuration object. In a web hosted Web API:

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new DummyHandler());

As we discussed, the order of registering a handler is very important and defines the size of the Russian doll, higher it is in the list, more powerful it will be as it becomes the soonest receiving the request and last receiving the response (hence more flexibility and breadth of operation).

UPDATE 06/08/2012:  The order of calling message handlers has changed for RTM release. So in RTM, first item is called first for request and last for response.

Registering a per-route message handler(s)

This is easy and is at the same time of registering the route itself. Here we register MyMessageHandler:

IHttpRoute route = config.Routes.CreateRoute(
 routeTemplate: "api/MyRoute",
 defaults: new HttpRouteValueDictionary("route"),
 constraints: null,
 dataTokens: null,
 parameters: null,
 handler: new MyMessageHandler());

config.Routes.Add("MyRoute", route);

One might wonder, it would have been great if we could register a collection of delegating handlers along with the actual handler. In fact we can! Se let's say we have two DelegatingHandler implementations as RussianDoll_1 and RussianDoll_2. So we can now say:

var handler = new RussianDoll_1()
 {
  InnerHandler = 
   new RussianDoll_2()
   {
    InnerHandler = new MyMessageHandler()
   }
 };

IHttpRoute route = config.Routes.CreateRoute(
 routeTemplate: "api/MyRoute",
 defaults: new HttpRouteValueDictionary("route"),
 constraints: null,
 dataTokens: null,
 parameters: null,
 handler: handler);

config.Routes.Add("MyRoute", route);

Conclusion

In this post, we briefly reviewed the history of two types of HTTP pipeline components: the one that is responsible for processing a request and sending back a response, and the other, a mid-stream component in the HTTP pipeline sniffing the incoming and outgoing request/response which can sometimes intervene in the message processing.

In brief, Web API heavily uses the abstraction of HttpMessageHandler and DelegatingHandler - latter inheriting from the former. Web API allows for registration of global message handlers or per route handlers. In the next post, we will review some of the real-world use cases of Message Handlers.

Sunday, 6 May 2012

Performance comparison of object instantiation methods in .NET

In the previous post, I compared performance of various methods of code invocation that are in our arsenal in .NET framework.

Last night I was reviewing ASP.NET Web API Source Code that I noticed this snippet:
private static Func<object> NewTypeInstance(Type type)
{
    return  Expression.Lambda<Func<object>>(Expression.New(type)).Compile();
}

But surely, compiling a lambda expression is really costly (as we have seen in the last post), why shouldn't we use simply do this (if we are suppose to just return a Func):
private static Func<object> NewTypeInstance(Type type)
{
    var localType = type; // create a local copy to prevent adverse effects of closure
 Func<object> func = (() => Activator.CreateInstance(localType)); // curry the localType
    return func;
}

Well, I asked this very question from Henrik F Nielsen, ASP.NET Web API team's architect. And he was very helpful getting back to me quickly that "compiling an expression is the fastest way to create an instance. Activator.CreateInstance is very slow".

OK, I did not know that, but it seems to be a good topic for a blog post! So here we are where I compare these few scenarios:

  1. Direct use of the constructor
  2. Using Activator.CreateInstance
  3. Using a previously bound reflected ConstructorInfo (see previous post for more info)
  4. Compiling a lambda expression every time and running it
  5. Caching a compiled lambda expression and running it (what ASP.NET Web API does)

Test and code

In this one, I could get a bit more imaginative with my code since in the last post I already established overhead/merits of various code invocation methods. For the object to construct, I use a simple class which has a default parameterless constructor. Results will be different using a parameterful constructor but I think parameterless constructor is a more pure case.

So I have created a few Action extension methods to perform the tedious repeated snippets in the last post. Each method runs 1,000,000 times which is not high enough but as we will see (and have seen in the last post), compiling a lambda expression every time is really slow so 10 million would be very high.
public class ConstructorComparison
{
 static void Main()
 {
  const int TotalCount = 1000 * 1000; // 1 million
  Stopwatch stopwatch = new Stopwatch();
  Type type = typeof(ConstructorComparison);
  var constructorInfo = type.GetConstructors()[0];
  var compiled = Expression.Lambda<Func<object>>(Expression.New(type)).Compile();

  Action usingConstructor = 
    () => new ConstructorComparison();
  Action usingActivator = 
    () => Activator.CreateInstance(type);
  Action usingReflection = 
    () => constructorInfo.Invoke(new object[0]);
  Action usingExpressionCompilingEverytime =
   () => Expression.Lambda<Func<object>>(Expression.New(type))
    .Compile();
  Action usingCachedCompiledExpression = 
    () => compiled();
  Action<string> performanceOutput = 
    (message) => Console.WriteLine(message);

  Thread.Sleep(1000);
  Console.WriteLine("Warming up ....");
  Thread.Sleep(1000);

  Console.WriteLine("Constructor");
  usingConstructor
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Activator");
  usingActivator
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Reflection");
  usingReflection
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Compiling expression everytime");
  usingExpressionCompilingEverytime
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Using cached compiled expression");
  usingCachedCompiledExpression
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.Read();
 }
}

public static class ActionExtensions
{
 public static Action Wrap(this Action action, Action pre, Action post)
 {
  return () =>
       {
           pre();
           action();
           post();
       };
 }

 public static Action OutputPerformance(this Action action, Stopwatch stopwatch, Action<string> output)
 {
  return action.Wrap(
   () => stopwatch.Start(),
   () => 
    {
     stopwatch.Stop();
     output(stopwatch.Elapsed.ToString());
     stopwatch.Reset();
    }
   );
 }

 public static Action Repeat(this Action action, int times)
 {
  return () =>  Enumerable.Range(1, times).ToList()
   .ForEach(x => action());
 }
}

Results and conclusion

Here is output from the program:

Warming up ....
Constructor
00:00:00.0815479
Activator
00:00:00.1732489
Reflection
00:00:00.4263699
Compiling expression everytime
00:02:11.5762143
Using cached compiled expression
00:00:00.0855387

So as we can see:

  • Using a cached compiled expression is almost as fast as the constructor 
  • Using Activator is x2 slower
  • Using reflection is x5 slower
  • Compiling a lambda expression every time is really slow: in this case + x1000 times slower 
So indeed as Henrik said, having only the type of the class, using a cached compiled expression is the fastest method.

Sunday, 22 April 2012

ASP.NET Web API Series - Part 4: Dependency Injection

[Level T2]

In this post, I will review the dependency injection features of the ASP.NET Web API. There are a few posts out there but I felt there are areas still not covered so I am exploring the dependency injection options. I do not try explaining what Dependency Injection (DI), Inversion of Control (IoC) or Service Location are. If you are not familiar with these you perhaps first need to get a grasp by reading numerous resources out there.

Until ASP.NET MVC 3 none of the Microsoft products had any IoC interoperability. In ASP.NET MVC 2 you had to resort to replacing default controller factory with your own and server controllers by using service location. In WCF you had to provide your own factories using code or config which were not great. But ASP.NET MVC 3 for the first time relinquish its hold on object creation and acknowledged the need for DI as more teams embraced it.

ASP.NET Web API beta has a built in support for dependency injection. Just be careful that there are breaking changes in the ASP.NET Web API source code and the model has changed (it has been simplified). I will shortly explain beta release and then move on to the source code which the final release will probably look more like it.

ASP.NET Web API beta release

[Remember, this stuff has changed] DI is based on setting a dependency resolver (technically a service locator) on the HttpConfiguration object. This object is on the GlobalConfiguration object as a static property (web hosting) or in case of self hosting on HttpSelfHostConfiguration.

So in case of web hosting you would use:
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(myResolver);
There are basically 3 options when it comes to registering a dependency resolver:

  1. An instance of an object implementing IDependencyResolver dependency which has two methods: GetService and GetServices
  2. An instance of an object which has these two public methods: GetInstance and GetAllInstances. No interface needed and Web API will use reflection to call methods.
  3. Passing two delegates that return an instance or instances for a particular type

ASP.NET Web API source code release

This has been simplified and unified so there is only one option: using IDependencyResolver

There is one change in IDependencyResolver though: in addition to GetServeice and GetServices (which now is in IDependencyScope interface implemented by IDependencyResolver), there is a BeginScope method. 

BeginScope according to documentation is:

Starts a resolution scope. Objects which are resolved in the given scope will belong to that scope, and when the scope is disposed, those objects are returned to the container. Implementers should return a new instance of IDependencyScope every time this method is called, unless the container does not have any concept of scope or resource release (in which case, it would be okay to return 'this', so long as the calls to are effectively NOOPs).
This is particularly important if you leave responsibility of lifetime management of your objects to your DI container.


Developing a simple Dependency Resolver for AutoFac


AutoFac is my DI framework of choice (I have used Windsor and Unity before). So here I will write a few lines of code to hook AutoFac into ASP.NET Web API.

All you need to do is to implement IDependencyResolver and then create an instance of your object and use SetResolver on the configuration (see above) instance.

Your Dependency Resolver is not supposed to throw exceptions but it can return null in case the type is not registered.

ASP.NET Web API also tries to use Dependency Resolver (and in case you have provided your own will use yours) to resolve its own dependencies. This could have placed a big burden on such a dependency resolver to have knowledge of all ASP.NET Web API dependencies but the implementation is as such that Web API will use the objects that you return for dependency resolution and if you return null, it will use the default.

So here is the code for the simple AutoFac dependency resolver:
public class AutoFacDependencyResolver : IDependencyResolver
{
 private ContainerBuilder _builder = new ContainerBuilder();
 private IContainer _container;

 public ContainerBuilder Builder
 {
  get
  {
   return _builder;
  }
 }

 public void Build()
 {
  _container = _builder.Build();
 }

 public IDependencyScope BeginScope()
 {
  return this;
 }

 public object GetService(Type serviceType)
 {
  object resolved = null;
  if (_container.TryResolve(serviceType, out resolved))
   return resolved;
  else
   return null;
 }

 public IEnumerable<object> GetServices(Type serviceType)
 {
  object resolved = false;
  Type all = typeof(IEnumerable<>).MakeGenericType(serviceType);
  if (_container.TryResolve(all, out resolved))
   return (IEnumerable<object>)resolved;
  else
   return null;

 }

 public void Dispose()
 {
  if(_container!=null)
  _container.Dispose();
 }
}
Things to note are:

  • We expose the builder so the client can register the components.
  • We expose Build() method so at the end of registration, Build() is called. Ideally we should hide the builder and expose it through AutoFactDependencyResolver methods so that build could not be directly called on the builder by the client.
  • AutoFac inherently does not have a ResolveAll method but instead you may resolve IEnumerable<T> in which case works as ResolveAll.
  • Please note that we had to use TryResolve so that no exception is thrown. Alternatively you may use a try/catch block and return null in the catch (but that could mask other exceptions)  
OK, let's imagine we have a controller which is dependent on loggers:

public interface ILogger
{
 void Log(string value);
}

public class TraceLogger : ILogger
{
 public void Log(string value)
 {
  Trace.WriteLine(value);
 }
}

public class DebugLogger : ILogger
{
 public void Log(string value)
 {
  Debug.WriteLine(value);
 }
}

public class DiTestController : ApiController
{
 private ILogger _logger;
 private List<Ilogger> _loggers;

 public DiTestController(IEnumerable<Ilogger> loggers)
 {
  _loggers = loggers.ToList();
 }

 public string Get()
 {
  _loggers.ForEach(x => x.Log("Get"));
  return "Dependency Injection";
 }

}

So the controller will use ForEach to call Log on all ILoggers passed to it. In order to register the Dependency Resolver, all we have to do is this:
AutoFacDependencyResolver resolver = new AutoFacDependencyResolver();
resolver.Builder.RegisterType<TraceLogger>().As<ILogger>();
resolver.Builder.RegisterType<DebugLogger>().As<ILogger>();
resolver.Builder.RegisterType<DiTestController>();
resolver.Build();
config.DependencyResolver = resolver;

Config object here is a reference to GlobalConfiguration.Configuration (in case of web hosting) or an instance of HttpSelfHostConfiguration (in case of self-hosting).

Conclusion

Dependency injection has gone through breaking changes from ASP.NET Web API beta to the source code release. Registering your own dependency injection provider is easy and all you need is to implement IDependencyResolver and then use SetResolver method on the HttpConfiguration (depending on your hosting scenario) to register it. ASP.NET Web API will optionally try using your resolver to resolve its own dependencies but you do not have to register the defaults. Be careful to catch any dependency resolution error.



Saturday, 21 April 2012

Web API Governance - Life in a schemaless world (Take 2)

Introduction

[Level C4] While classic web services used WSDL for their schema and description, emerging Web API mainly relies on documentation. This requires human effort and with the rising popularity of Web API it could create problems in maintenance, change management and extension of Web APIs. The solution is automation and this article reviews challenges and possible solutions.

Rise of the Web API


NOTE: This is take 2 of my post, with some updates.

I am very excited at the moment. Microsoft has just released its beta version of its best HTTP implementation to date. ASP.NET Web API has embraced HTTP exposing its full goodness. No more clutter of SOAP-based RPC services. Lean and mean.

So life cannot be any better? Hmmm.. it can! Away from all the hustle and bustle and buzz of the REST APIs (whether they are really RESTful is another discussion which to be frank I am not interested any more), it is important to be objective and almost clinical about the technology. It is important to be able to look back, and see how far we have come so far and yet learn lessons from the past and use the solutions of the previous generation if they are still relevant (in IT terms it is 5-10 years depending on the technology).

There has been a movement in the industry to question the basics. This is good, it weeds out unnecessary abstractions. We have had RDBMS for years now we want NoSQL. We have had XML/SOAP now we want JSON. We have had complex layered server side architecture now we want close to the metal, like node.js or sinatra/nancyfx. Scripting was bad, type safety was good and now scripting is good and everyone wants to escape type safety.

OK, we have had SOAP services and we have never been happy with them. They were clunky, heavy and complex. Now we got Web API which is so much better. But let's have a look at the problems that classic Web Services started tackling and in fact, did a good job in some cases.

Governance in Web Services

This is an SOA term that revolved around managing and organising web services in a consistent fashion. This  would protect the clients as well as allowing the vendors to manage the life of the services. 

Some of the aspects of Governance include:
  1. Contract and description: mainly through WSDL
  2. Registry service and discovery: mainly through UDDI and later WS-Discovery
  3. Versioning
  4. Exception handling
  5. Security and access control: mainly through Web Service Extensions and later WS-Security
To be fair, the work in the area produced some useful technologies and standards. One problem being they are mainly based on the RPC style web services as such not quite useful in the REST style Web API. The issue is problems do still exist and question is whether we do have appropriate tools to address them.

What did we lose on the way?

OK, I am trying to imagine 3 years from now - I am sorry but I see chaos. A good proportion of existing Web Services will be moved to pure HTTP Web APIs. I think it is very likely that the RPC mentality stays with the developers and we end up with RPC style Web APIs. And now what? We are even more vulnerable with no classic Governance safety net.

With classic web services (and WCF), all you needed to point to a web service was its WSDL. It would provide the contract, schemata, faults, security requirements, endpoint addresses and some description. If you would update your service, the WSDL (which it could be generated on the fly) would be updated. In fact in most cases all you needed was the service endpoint address, from where you could get all informations you needed (e.g. by just placing ?wsdl at the end of the address).

We do have some replacements here in HTTP APIs. For example, we do not need SOAP fault to be defined in the WSDL, since we have HTTP error codes. We do not necessarily need WS-Security as we have OAuth/OpenID/etc token based federated security. Discovery is not really a big issue and hypermedia can help in this regard. 

OK, the question is do we need all that stuff? REST (and HTTP as its sole implementation) is Turing-complete. An agent should not need any priori knowledge to be able to use a service. It can use OPTIONS to discover verbs, it can use content-negotiation to ask for media types it can understand and use hypermedia to navigate through the resources of a server.

Turing-completeness is great but to be honest, it still belongs to Sci-Fi novels. We are not there yet. I believe for great development experience and maintenance, we still need schema. Most web APIs are about interacting with data. Probably somewhere around 80-90% of Web APIs out there serve JSON. What does application/json content type exactly tell about the actual JSON being served? Are we currently writing agents/applications that can intelligently adapt and consume whatever JSON being served to them? 

I was listening to one of the episodes of MashThis podcast and the theme that was coming on good Web API was always good documentation. Nothing beats a good documentation but how many of us developers are good in this? Human effort to create and maintain a good documentation covering schema and description is going to be big. I think we need some automation here.


Challenges

I originally suggested using media types so that client could request not the data but the schema of the data. In this update, I am going to look at other options as well as semantic challenges for providing schema and description. In fact, I am not going to propose a solution, I will use this post to describe the problem. I hope this will start a fruitful discussion so please feel free to join in.

HTTP and schema?

Schema for an HTTP API (intentionally not using the word REST API) might initially seem a little bit odd. Actually the word does not appear at all in the RFC 2616. As far as the HTTP is concerned, server will allow the agent to interact with the resource using URI using the verb and associated headers. It is up to the agent to engage in content negotiation and interpret the result.

I personally think the problem of schema and description is inherently orthogonal to HTTP. A resource does not necessarily have to have a schema - other than the schema assumed by the content-type. For example, when a server responds to a GET request for an XML page using /foo/api/2 URL, it just serves the page which ideally is conformant to XML schema. But even well-formed XML does not explain enough about the structure of the document and its internal schema. In fact XML instance will contain its schema but server (unlike RPC style web services) might not able to return an XML schema - since /foo/api/3 might have a completely different schema.

But let's bear in mind this can simply be an option. Server might support the schema/description and return, or it can return a 404 error. In fact, schema can be service-specific or URI specific, i.e. it could refer to /foo/api/{id} or /foo/api/690. In this case, while schema is relevant for different ids (as they have different schema), service description will be the same. Hence any solution must consider this variability.

URIs and URIs routing formats

It is very common in the Web API space to provide URIs containing placeholders to pass data fragments to the API. In our example, /foo/api/690 means id=690. Alternatively, data could be sent as query string parameter such as /foo/api?id=690.

The schema or description could be different based on the parameters passed.

One issue to be considered is that it is possible agent does not know about an actual existing resource (for example does not know a valid id to be passed to return an actual resource) and all it knows is the URI format. Solution must be flexible enough to provide a schema for the API method if a generic schema exist for the URI format (i.e. all documents at /foo/api/{id} have similar schema)

Priori knowledge

One of the main focuses of HTTP spec is to remove the requirement of the priori knowledge from the agents. Agent is encouraged to explore server resources and functionality (e.g. OPTIONS) and server guides the agent using hypermedia.

With developing Web API that requires documentation, we are adding back this priori knowledge requirement. This is not good. But in the absence of a standard we will end up with nothing much better than a convention - which itself is a priori knowledge. So ideally this process must involve a standard or even a standard proposal. A lot of useful technologies out in the cloud are still in the proposal phase, namely OData, JSON Schema and HAL.

Security

A schema must ideally provide a detail on the security requirements of the service. This is especially important for authentication schemes supported by the server (e.g. basic authentication, federated identiy, etc).

Schem and description as a single resource?

Decision needs to be taken to whether serve description and schema of the service separately or provide them as a single document. The more I think about it, the more I feel it probably has to be a single document.

Possible Solutions


1- Using content type

Since JSON and XML are two most popular formats being served, for now serving schema can practically be limited to these media types.

Let's Look at this request:
GET http://localhost:50459/api/HelloWorld/1.1
User-Agent: Fiddler
Host: localhost:50459
And response is:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 17 Apr 2012 21:46:38 GMT
Content-Type: application/json; charset=utf-8
Connection: Close 
"This"
So as we can see, media type returned is JSON and the value is a simple string. Now if we send a request asking for a JSON schema with accept header of  application/schema+json, we get back this:

GET http://localhost:50459/api/HelloWorld/1.1
Accept: application/schema+json
Host: localhost:50459 
And response is:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 17 Apr 2012 21:46:38 GMT
Content-Type: application/schema+json; charset=utf-8
Connection: Close 
{
  "type": "string"
It is true that JSON schema is still in draft status but with this format becoming more and more popular, it is inevitable that we restore some structure in our Web API.

Since XML already has an established schema language, we can use XML Schema but one problem is that XML Schema has a content type of application/xml or text/xml. So either we nominate an alternative content type (such as application/schema+xml) or use URI to denote request for schema (ideally in the format of optional query string parameter although that will still be part of the URI).

Same applies to the description of the service. It is ideal that the documentation of the service id provided by the service itself. For description, agent can use a special content type (for example x-text/docs) or using a query string parameter.

2- Using hypermedia

Server can include separate links to schema and description while serving the actual resource. Payload can be HAL or alternative implementations of hypermedia.

A HAL payload can look something like:

{
  "_links": {
    "description": { "href": "/description" },
    "schema": { "href": "../../schema?type=MyDto" }}
  },
  "_embedded": {
    "MyDto": [
...

Server could have an implementation convention to treat description and schema URL fragments as special paths and serve appropriate resources. Please note that all the data needed to provide the schema could be located in the URL, e.g. type of the serialised payload is appended as a query string parameter so the server does not even have to know about the API method queried about.

This imposes a burden on the agent to understand such complex structures.

Also bear in mind, an ideal solution must be able to explain the output schema as well as input schema. For POST and PUT verbs, a JSON payload could be sent to the server to be stored and server must be able to provide not only the output but also input schema.

3- Using a URL convention

Basically in this solution, agent has a priori knowledge of a convention (or a standard) by which can interrogate the server and ask for schema and description of the services available on the API server. For example /foo/api/$list could provide a list of methods (I know, it sounds like RPC but I have no better word) avilable on the server. $schema can provide the schema and $description the description for the service.

Conclusion

Web API needs to look back and consider solving some of the problems solved by classic Web Services. It is very likely that with the migration of classic web services to Web API we find ourselves in a chaotic situation. This area needs to be explored and all options to be considered hence a debate on the subject is welcome. It is likely that we might need a convention/standard for describing our Web APIs.