I have been a Netflix customer for several years now and I just love the service. As a software developer, I was quite excited when I heard that they had opened up a Web Service API to access their service. Wasting no time, I headed over to http://developer.netflix.com to grab a piece of the action. However, my enthusiasm quickly waned as I started plowing through their documentation. Initially, I came across terms that were quite familiar: REST, XML, etc. But soon, I was confronted with some fundamental problems, such as:

The documentation is quite extensive, but is only available in an online format. It would have been really handy to download a PDF to print out and browse offline at my leisure.

They use some peculiar formatting that looks great in a browser, but when I printed it, pretty much all of the diagrams were lost or chopped to bits.

The details are sometimes way oversimplified, or sometimes quite obtuse.

Through diligent effort searching for better explanations for their terminology, and any code that might demystify things for me, I finally was able to assemble some code the demonstrates the Netflix APIs - and it turned to be quite simple in the end. This is the first of a series of articles that describe the fundamentals of the Netflix APIs and demonstrate how .NET applications can access the Netflix services programmatically.

One last word about the Netflix documentation before we proceed. Please don't get me wrong. I don't mean to sound harsh about the documentation they produced. It's enough work just publishing a reliable and well designed API set, much less producing quality documentation. I give my utmost kudos to the Netflix team for the work they've done, and hope that my additional clarifications will be of benefit to everyone. Furthermore, my first encounter with the documentation was right after the API was released, so it's understandable that it was a bit rough. It has indeed improved subsequently; however, there are still areas remaining that these articles can help clarify.

And finally, you might want to skip ahead as you're reading to the Glossary of Terms at the end of this article. It lists some of the terminology that I'm using and how it relates to the terminology in the Netflix documentation.

This article will introduce you to the technologies used by the Netflix APIs:

REST

OAuth

I realize that many of you CodeProject readers do not have access to the Netflix service. I hope that you will find the technical information in these articles of merit even if the practical application of the example code is of lesser benefit.

The first step in developing a Netflix client application is signing up for a developer account. There is a link on the Netflix Developer Network home page that leads to a form where you can sign up for a developer account. This form requires you to enter some basic information about yourself, including a name and password you would like to use for this account. After completing this form, click Register, and you will be presented with a confirmation page that informs you that you will be receiving an e-mail message with further instructions.

The e-mail message contains a link that takes you back to the Netflix account management site to confirm your developer account request. You will find a link on this page that will take you to another form where you register your application.

Note: You are only allowed to register one application with each developer account. If you wish to develop multiple applications, you must create a separate account for each application.

On the application registration form, you will fill out the basic information about your application. The most important field on this form is, "How did you hear about this API?". You must, of course, answer "Codeproject.com"! When completed, click Register Application and you will arrive at a page that confirms your application registration.

The Application Registration page contains several items of information, the most important of which are:

Key - This is generally referred to as the "Consumer Key" and represents your application's identity when making Netflix API requests.

Shared Secret - Also referred to as the "Consumer Secret", this is a secret token that is used when digitally signing your Netflix service requests. Without this token, no one can falsify a service request claiming to be you.

You may wish to print this page, or copy and paste the information into a file, for later reference. But don't worry, Netflix also sends you an e-mail message containing your consumer key and shared secret for archiving in your records.

A non-authenticated request can be constructed in a simple URL sent from a Web browser. This request requires only your Consumer Key and does not need signing. Per the Netflix API documentation, the only non-authenticated request currently supported is the auto-complete catalog search. The following example demonstrates this type of search, where YourConsumerKey is the consumer key you received for your application when you created a developer account.

You can copy and paste the preceding request example into your favorite browser, insert your own consumer key, and the results returned should be a list of movie titles associated with the term "Casper".

As I mentioned earlier, I was quite mystified by the Netflix documentation's explanation of the fundamentals of accessing the APIs, as described in their Authentication Overview topics. They tried, in my opinion, to weave too much technical information together in one big blob, which resulted in my spending more time trying to decipher their documentation conventions than actually understanding the application of the various technologies. I will not attempt to rewrite the Netflix API documentation in its entirety here, but rather to paraphrase their introductory overview in what, I hope, is a more logical and comprehensible manner.

The Netflix API is base on REST, which stands for Representational State Transfer. Having been a SOAP (a.k.a., Web Services) developer for some time, I occasionally find myself having to describe REST to other SOAP developers. My short answer is that REST is a Web Services protocol where you simply put all of the information about the request into the HTTP request URI and query string parameters. I don't want to dwell on the differences between SOAP and REST in this article, but this comparison of the two is a brief way of describing how REST works. For those of you who are familiar with SOAP, or simply as a way of describing REST, here's my version of how the two protocols compare:

SOAP

REST

Action is contained in the SOAP header (WS-Transfer).

Action is specified by the HTTP method (GET, POST, PUT, DELETE).

Routing information is contained in the SOAP header (WS-Transfer).

Routing information is appended to the base URI.

Parameters are passed in the body.

Parameters are passed in the URI and query string. Because of this, the parameters must be URL encoded (also referred to as percent-encoding by those who may be conceptually challenged).

Errors are returned as SOAP faults.

Errors are returned as HTTP error codes. If you're really lucky, you might get a bit of detail about why the request was rejected, but usually, you get just an error code.

Note that the query string is wrapped in this example for clarity, and that YourConsumerKey is the key for your Netflix developer account. So what does all this mean?

The first thing you need to make a service request is which HTTP method will be used (GET, POST, and so on).

The next item is the URL, formally called the "service endpoint", to which the request will be directed.

Lastly, a list of parameters that provides details about what information you wish to obtain, and some additional OAuth security parameters. Note that the query parameters are specified in alphabetical order, formally known as canonicalization. The important thing to observe here is that the two application-provided request parameters are max_results and term - everything else is for the OAuth security. Because of the canonicalization, the max_results and term parameters wind up at the beginning and end of the query string, respectively.

Now, let's take a look at the OAuth parameters individually.

OAuth Parameter

Description

oauth_consumer_key

This is the consumer key that was issued to you for your application. This is what identifies your application as an authorized Netflix service consumer.

oauth_nonce

A nonce is simply a unique identifier, somewhat like a GUID, that can be considered as having multiple purposes:

It represents a unique value for each message so that any given message cannot be resent, thus preventing "replay" attacks.

It can also represent a message identifier, somewhat equivalent to the <MessageID> in a SOAP WS-Addressing header. If Netflix supported asynchronous service requests, and included the nonce in the service response, this identifier could be used to correlate responses with their original requests.

oauth_signature_method

Describes the hash method used to generate the digital signature (to be described shortly). This is always HMAC-SHA1 for Netflix API requests.

oauth_timestamp

Indicates the date and time at which this request was created. This timestamp also prevents replay attacks, as previously described. Per the OAuth specification, the "timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT". In simple terms, it's the good old UNIX time format.

Now that we have the REST request and the OAuth security parameters prepared for the HTTP query string, all that's left is to add a digital signature and we're ready to create our Web request.

The signature is, as previously mentioned, a simple HMAC-SHA1 hash, which is readily available in the .NET System.Security.Cryptography namespace. The signature is generated by concatenating the following elements from the request into what the Netflix documentation calls a "base string", which is then fed to an instance of an HMAC-SHA1 hash generator class.

The HTTP method.

The base URL.

The query string parameter list.

The "Consumer Key" and "Consumer Secret" that were provided to you when you created your developer account.

Using the request example from the beginning of this section, this is the equivalent base string:

After all of this preparation, you are ready at long last to send off your request, which is now quite simple. The request is sent over HTTP using a GET method, to the URL representing the service endpoint of interest, and the query parameters and digital signature are appended to the request. If everything is constructed correctly, you will receive an XML document in return that contains the information you requested.

During my research on OAuth, I was fortunate to stumble across a nice bit of C# code that encapsulates all of the effort required for creating a properly formed OAuth request written by Eran Sandler (see the comments in the code for additional details). There are several public methods in this module, and I also added some tweaks of my own, and ultimately I found the following method to be the most appropriate for my purposes:

Note that the OAuthBase class takes care of all the URL encoding required for the query string parameters when it constructs the normalizedRequestParameters output parameter. However, the signature does require URL encoding before it is appended to the rest (ha ha, no pun intended) of the request.

Also note that I'm using the UrlEncode function provided by the OAuthBase class. This is very important! You may be tempted to use the more familiar URL encoder provided by the .NET HttpHelper.UrlEncode method; however, it returns the encoded characters in lowercase. Netflix requires the URL encoded characters to be in uppercase, which is what the OAuthBase class provides. There is at least one tale of woe in the Netflix Developer Forum where this minor detail was overlooked.

Whew! Now all we have to do is to fire off the request and (hopefully) get back a bucketful of data. For this example, I'm using a simple synchronous HTTP request using the WebRequest/WebResponse classes.

The example code is an application that searches for Netflix titles. It requires three inputs: your consumer key, your consumer secret, and the term for which to search. Optionally, you can specify the maximum number of results to return, or choose zero to return the default of up to 25 items. The constructed REST request and the resulting response from the Netflix API call are displayed when Search is clicked.

The returned data is an XML document that contains information from the search request. It is fairly obvious what everything means; however, you can also find details in the Netflix API documentation if you need help in understanding it. In a subsequent article in this series, I will show you how to parse and use the data contained in this response.

So, there you have it. I hope this article will save you lots of time and confusion in writing your own Netflix client application. In future editions of this series, I'll demonstrate:

How the Netflix data is structured and how to efficiently parse the requested information.

How to obtain permission to access a subscriber's account, and how to view an account using Protected Requests.

How to modify account information, such as making changes to a subscriber's movie queue, using Protected Requests.

I must also point out that the code example in this article, as in the subsequent articles, will be evolving over the course of this series. Please understand that each one of these examples is written to demonstrate a particular aspect of the Netflix API and therefore they are not intended to represent a complete library of the Netflix API functionality.

One last item is that I want to point out some differences in the terminology that I'll be using in these articles and how it relates to the terminology found in the Netflix documentation. I prefer to use some specific, or perhaps more conventional, terminology, and so here is a cross reference for you to keep in mind as you read these articles.

Share

About the Author

I am a programmer/writer, specializing in developing SDKs, and work for a rather well known software company in Redmond, WA. More information than you could possibly be interested in knowing can be found at NetDave.com.

The Netfilx API is for accessing their movie and user queue management database. They don't offer a simple API for streaming movies, along with all of the associated DRM, to the public. You may have your 1 back.

Thanks for posting this. Netflix changed their request URL format and I haven't gotten around to updating the articles. How nice of them to break the request format and not maintain backwards compatability.