Archive for the ‘Development’ Category

In a previous post, we looked at how to consume a live streaming API from Twitter.  That was great and all, but you’re not going to become the next Twitter by consuming content — you need to have your own live streaming API.  In this post we’ll look at how to create a basic streaming API that others can open a streaming connection to and get real-time updates.

So, what groundbreaking web service will we be exposing to the masses?  We’ll be streaming the web server’s current datetime!  Ingenious, I know!  Hopefully, you’ll be able to adapt this to a slightly more engaging experience.

To start, let’s just take an ASP.NET MVC project and code the default controller action.  We clear all the headers of the response and add the “application/json” header.  Since we won’t be returning a view in the traditional sense of ASP.NET MVC, we don’t have to create an actual view.  We’ll just pause the thread for 1 second and then return the current timestamp for as long as the service is running.

On the consumer side, we’ll just refactor the code we had in the previous post to connect to the URL of the project we just created.  I’m running in on the local development machine so your port will likely be different.

You’ll notice we added some exception handling logic in case we lose our connection to our streaming API.  In this case, we’ll just keep trying to re-connect to the stream.  I’ll show you a sample of this in the last part of the post.

Once we have all the bits in place, we run the ASP.NET MVC application first so it is ready to start handling requests.  Then, we create multiple instances of our consumer console application to simulate multiple clients connecting to the streaming API.  You’ll end up seeing something like this:

To simulate what would happen on the consumer side if there was a broken connection or other exception on the server side, I killed the local development server for a few seconds and then restarted it.  Below you can see that we recovered after a few exception handling loops.

Of course, this post was just intended to provide a possible option for implementing a streaming API with ASP.NET MVC.  For a more realistic scenario you would likely have a queue listener around our Thread.Sleep() code.  As messages are picked up from the queue, you could stream it out and immediately start listening for the next message on the queue.

In a follow-up post, I will demo this same concept using Node.js.

Hope this helps.

I’ve always been a fan of how Twitter organized their API.  Particulary, I enjoyed being able to change the format of the response by just changing the extension of the URL from JSON to XML.  A typical Twitter API call looks like this:

http://api.twitter.com/version/statuses/public_timeline.format

So while this public timeline call will return XML:
http://api.twitter.com/1/statuses/public_timeline.xml

This one would return JSON:
http://api.twitter.com/1/statuses/public_timeline.json

The proper REST way to do this is by changing the headers in your request to ask for a particular file format.  Indeed, an implementation utilizing request headers has already been written.  However, I prefer Twitter’s implementation which coincidentally seems to be a feature of the Scala / Lift framework.  To accomplish this with ASP.NET MVC, we are going to build an attribute that checks the incoming request and then attempts to render the resulting model in the selected format.

First, some words of caution.  I don’t think this method will scale if your API / web application takes off.  Although it is a great example of the DRY (don’t repeat yourself), code-once software development practice, it does somewhat tightly couple your API to your front end.  Twitter faced a similar situation when their API was hosted on the same domain as the web application.  Eventually, Twitter moved the API to api.twitter.com.  This practice allows the API to evolve independently of the front-end of your application.  With that warning in mind, let’s dive into the code.

They way we’ll implement this functionaly is to develop a custom action attribute which will check for a “format” parameter on each request to decide whether to return the model as a JSON, XML or the default view that the controller will return. This is slightly different from Twitter’s implementation but it simplifies some of the routing issues we would have with ASP.NET MVC.  Using an API-driven development approach, I’ll start with an existing controller and add a (non-existent).  This gives me an idea of how it would work.

I could add some additional parameters at this point to restrict which formats to accept, but we’ll leave that out for now (KISS – Keep It Simple Stupid!).  Next we’ll just generate the class using the smart tag in Visual Studio which will create the stub for it.  We want this action filter to execute before the response is returned to the client but after the data model has been populated.  This implies we’ll be overriding the OnActionExecuted method:

At this point, everything should build.  Our next step is to create two custom ActionResult subclasses which will return either Xml or Json representations of the model you pass in.

ASP.NET MVC includes a JsonResult which we’ll use for the JSON format.  Although there is no XML equivalent, the MVCContrib library does have an XmlResult class.  You can download the bits here to provide the XmlResult class (along with some other very useful features).  Add the assembly as a reference to your project.

Now we have the two ActionResult’s we need to implement the solution.  Below is a screenshot of the finished method.  Essentially, we’re looking into the filter context to find the file extension.  Depending on if it’s json or xml, we use a different action result serialization technique.

Notice that we need to set the JsonRequestBehavior in order for this to work.  There are several security vulnerabilities which you should explore before defaulting this behavior at such a broad level. Phil Haack details some of the issues with JSON Hijacking here.

That’s all there is to it.  Hope this helps!

Unless you’ve been living in a cave for the past several months, you know the about the major shift in web development called HTML5.  It seems everyone is talking about and justly so.  It was the number one top trends for 2010 and will continue to change how we write web applications.  Although the spec has not been finalized (indeed, its quite some time away from that), most mainstream browsers have already adopted some elements of HTML5 into their standard releases.

One common misconception is that HTML5 is just one big ‘thing’.  On the contrary, HTML5 is really a bunch of different features which are being defined by the HTML5 spec.  Unfortunately, most browsers do not support all of the features.  This makes it very important that you degrade gracefully when a feature is not supported by the browser.  It’s a small price to pay if you want to be on the bleeding-edge of web technology.  This is especially true if you’re a mobile web developer.

There are several techniques you can script to test for elements, properties of those elements, whether a property retains its value etc.  Instead of incorporating all these checks into your scripts, I would recommend taking a look at Modernizr.

Modernizr is an open source initiative to ease the pain of detecting HTML5 support on your pages.  So, what would commonly take several lines of code to check if the canvas element is supported and provides text functionality can be shrunk to only 1 line with Modernizr.
Without Modernizr:

function supports_canvas_text() {
   if (!supports_canvas()) {
      return false;
   }
   var hidden_canvas = document.createElement('canvas');
   var ctx = hidden_canvas.getContext('2d');
   return typeof ctx.fillText == 'function';
}

and with Modernizr:

if (Modernizr.canvastext)  {
   //supported
}

Eventually all browsers will support the full HTML5 spec and these checks will become unnecessary. But in the meantime, if you’re inclined to start leveraging HTML5, Modernizr is a must-have for your scripting toolset.