Along with an easy site with which you can access your account, there are many really cool Twitter clients out there. This is thanks to an exposed API that you can use to access all of Twitter’s features. The great thing is that this API uses a technology that WCF has embraced completely; I’m talking about REST. Though you can certainly use straight network programming to access and update your Twitter account, why not use the technology that Microsoft has put all their eggs into as far as communications programming is concerned? Twitter is, after all, all about communicating, right?

Just when you thought the social site craze had reached its peak, along came a new one that practically redefined simplicity. I mean, let’s be truthful. If you were to hear the idea for Twitter before it was released, there’s a good chance you would have shrugged it off and mumbled something like, “give me a break,” or “not another one.” But Twitter demonstrates the ultimate in good ideas. Not because of what it was designed to do, but because of what it has turned into.

In fact, the one question that Twitter asks you, which you can answer in those infamous 140 characters, “What are you doing?” is no longer accurate. What used to be a glorified IM tag is now used to post location updates, movie recommendations, expressions of emotion, and even technical information. In the .NET community, many find answers to programming issues and questions by locating Twitter entries in search results. Who would have thought; blogging 140 characters at a time.

A few months ago, I received with anticipation my issue of CODE Magazine in the mail. I open it to find an article called “Twitter Programming in Visual Basic” by none other than our dear editor-in-chief, Rod Paddock. I admit having a bittersweet reaction. Rod is a superb writer, fantastic speaker, and more importantly a good friend; but I had this idea too! I found myself kneeling in the sand at an all but covered Statue of Liberty yelling… OK, I was probably watching “Planet of the Apes” at the time. In truth, I tell this story in jest because Rod wrote a great article with which I think mine perfectly overlaps. Thanks Rod, for staying away from REST! (

Rod gives you a terrific introduction to the Twitter API and shows you how to access it using conventional Web-request programming. I strongly recommend that you read his article first because it’s a great prerequisite for this one. My goal here is to take you to the next level by bringing the Twitter API into the world of WCF. I mean, we have to, right? Microsoft has defined WCF as the platform for all message-based communication and that’s exactly what Twitter and its API are, so let’s continue with what I consider a team effort between Rod and myself.

What’s Your Motivation?

OK, so some of you are probably saying, “This is a cool deviation from conventional technical articles, but why on earth would I care about accessing the Twitter API?” Fair question. In fact, I asked myself the same question when I learned about it; so here’s what convinced me. I’ve noticed the increase use that Twitter accounts have received lately. My friends use it to state where they are. My colleagues use it to post tech info. Celebrities use it to hype what they’re up to. Believe it or not, I recently learned about an upcoming KISS tour by following Gene Simmons on Twitter (cut it out, I’m a fan). Commercial product companies have Twitter accounts to post update and fix info on their products. I’ve setup a Twitter account for CodeBreeze, my product (@CodeBreeze). All of the stated contexts here have a point of origin for the broadcasting of their information. For example, many of my friends and colleagues have either blogs or Web sites where they post technical articles and information. Rock bands have Web sites to hype their tour schedules and album release dates. And product companies, of course, all have Web sites from where they sell their products.

“Twitter has demonstrated to be one of the ultimate in good ideas; not because of what it was designed to do, but because of what it has turned into.”

All of these can be entry points to making Twitter posts, either manually or automatic based on data entry elsewhere. For example, I’m currently working on the next version of my company’s Web site where as soon as I post a new build of CodeBreeze, its Twitter account gets automatically updated with an entry that publicizes it. A band on tour can update their schedule on their Web site and have it update their Twitter account automatically. You can modify Windows applications to read Twitter information. For example, one of the ideas I’m toying with is showing a Twitter feed on the CodeBreeze Startup page so that it displays and allows entry of postings with a #CodeBreeze tag. The possibilities are only limited by creativity, but all of them require access to the Twitter API. See the sidebars for one of the more unique uses of Twitter I’ve ever seen.

And if none of these appeal to you, how about the fact that it’s just plain cool and fun programming!

Accessing Twitter, Redux

Twitter’s API uses a REST API. Later in the article, I’ll get into some details about REST and its context within the world of WCF. In simple terms, REST is a messaging protocol that embraces the world of HTTP by exposing its access points through conventional URLs. Just like you browse to an ASPX page to access an ASP.NET Web application that returns HTML pages, REST allows you to browse to a URL that returns data in a variety of formats. In a sense, it is not that much different from browsing to an ASPX page and getting data returned in the form of HTML markup.

The Twitter API can return XML, Atom, or JSON.

The Twitter API exposes all of its interface functions in the form of a URL that gets processed by Twitter’s servers and returns POX, ATOM, or JSON formatted data. The first two are actually XML data and very readable. POX stands for Plain-Old XML and is simply a representation of the data in the simplest XML possible. ATOM is XML-based as well but formatted to the ATOM industry standard. This way, consumers prepared to read ATOM feeds can obtain data in this format and know instantly how to parse it and make it usable. JSON stands for JavaScript Object Notation and represents a serialized format for complex JavaScript objects. Data in this format can be read by a JASON-aware application and deserialized into JavaScript objects.

Interestingly enough, the format I’ll use here with WCF is the simplest one, POX. You’ll see later how nicely Twitter data in plain-old XML format maps to WCF data contracts. So what exactly does Twitter XML data look like? I’ll give you the simplest of examples by accessing a quick public feed, attached to no account in particular.

You can browse to the URL “http://www.twitter.com/public_timeline” where you’ll see the Twitter public page where if you’re not logged in, you’ll see the Twitter public feed (all non-protected Twitter updates). See Figure 1 to see what this looks like. To see this feed in raw XML format, you can browse to “http://www.Twitter.com/statuses/public_timeline.xml”. The data that gets displayed on the browser is the same as the one you see nicely formatted in the Twitter home page, but this time it’s formatted into XML as follows, as show in Figure 2.

Figure 1: The Twitter Public Feed using the Web site.
Figure 2: The Twitter Public Feed - XML results from API call.

The URL I just showed you is a REST URL. The Twitter servers are configured to intercept requests that follow a certain URL format, query their databases, and return formatted XML. Twitter exposes many URLs, each used to retrieve information or update it. In fact, the list grows on a daily basis because REST-based URLs get parsed with both static and dynamic expectations on its parts. The URL, “Twitter.com/statuses/public_timeline.xml” is entirely static, meaning this is the URL and it does not change; it does what it does. However, there is another URL that the API exposes that returns a list of entries for a given screen name. That URL is “Twitter.com/statuses/user_timeline/{screenname}.xml”.

Most of this URL remains static all the time, but the portion I defined in curly braces actually is reserved for a specific screen name. For example, my screen name is miguelcastro67 so to access my feed using the API, you can browse to the URL “Twitter.com/statuses/user_timeline/miguelcastro67.xml”. This pattern of filling in parts of the URL to determine what kind of data you want is at the very core of a REST-based API.

Many URLs in a REST-based API like Twitter are analogous to function calls in an object-based API. For example, every posting in the Twitter database has an identifier. The Twitter API exposes a URL to access a specific posting using its ID (provided you know it, of course). The URL looks like this: “Twitter.com/statuses/show/{id}.xml”, with the {id} actually replaced with a posting ID.

Some URLs may be determined by the server to cause something to happen, other than just build and return data. For example, the URL “Twitter.com/statuses/update.xml?status={text}” causes your Twitter account to be updated with a new posting whose content replaces the {text} part of the URL. An API call like this one is a bit more complex because it requires some sort of authentication to take place. In fact, if you try to access such a URL right now, the browser will ask you for security credentials. Otherwise, you could just update anyone’s Twitter account (and wouldn’t that be fun).

In Rod’s article, he showed you how to access all of the above URLs using the Web-request objects available in the .NET Framework. He also showed you how to set up some security credentials and send them to Twitter for API calls that require them. I’m a strong believer in the step-by-step method of learning something, and learning that way to access the API is definitely the first step, so once again if you haven’t read Rod’s article, I encourage you to do so. I’ll wait.

Ok, you’re back, great. Now let’s see how all this fits into the world of WCF.

WCF & REST

In .NET 3.5, Microsoft enhanced WCF to become REST compatible. Anyone who’s worked with WCF should know by now the breakout of the various components that make up a well-designed service. I’m referring to the data contracts that store incoming and outgoing data structures, the service contracts that define service operations, the services themselves that provide service contract implementation, and of course the good ol’ configuration. On the consumer side, you have the same data contracts, the same service contracts, and instead of services, you have service access proxies. Oh yes, and you have configuration as well.

A REST Primer

I don’t want to turn this article into a full blown tutorial on REST, but I’ll give you some brief fundamentals because they will apply when we get back into Twitter soon.

A REST-based service, or restful service as it is better known, has all the service components I mentioned before. The primary difference is in the way operations are defined in the service contract. WCF-REST operations are decorated with the OperationContract attribute just like their conventional counterparts, but they’re also decorated with the WebGet attribute. This attribute, among other things, defines the format of the URL that will be able to access the operation. The WebGet attribute is in a namespace and assembly that may be new to you called System.ServiceModel.Web, so you’ll need to make sure you have a reference to it.

Say you have an operation defined in your service contract called GetProductList which returns a data contract called Product[] (note the brackets signify “array-of”). Ordinarily you would define this operation in a service contract and of course implement the method in your service class. To expose this as a REST service, you can decorate this operation with an attribute that looks like this:

[WebGet(UriTemplate =
"/products/get_products.xml",
        BodyStyle = WebMessageBodyStyle.Bare,
        RequestFormat = WebMessageFormat.Xml,
        ResponseFormat = WebMessageFormat.Xml)]

As you can see, the UriTemplate parameter of the WebGet attribute defines the format for the URL that will access this service operation. And the URL is of course appended to whatever the site is that services this operation. There are three other attributes here that cannot be ignored.

When a WCF Rest service serializes parameters and returns information, it has the capability of wrapping the data using infrastructure-provided XML elements. Many times you don’t want these extra XML elements and want to see the data in rawer XML format. Such is the case with Twitter data so I use the Bare enumeration value of the BodyStyle argument. Other possible values allow you to have the request, the response, or both pieces wrapped.

The RequestFormat and ResponseFormat arguments are set using the WebMessageFormat enumeration. This enum has two possible values, Xml and Json. The Twitter API can accommodate either one, but in the interest of simplicity for this article I’ll use XML.

The service that implements this operation will retrieve a list of products and build an array of Product objects, since this is the data contract to be returned. This is no different than writing any other WCF service. However, when accessing this service, a consumer can browse to the exposed service address and append “/products/get_products.xml” to the URL. This will return the list of products in an XML format with the XML elements mimicking the properties of the Product data contract.

You only use the WebGet attribute for HTTP-Get operations. To define an operation that will “post” information you would need to use the WebInvoke attribute, but its usage is the same with the addition of a Method argument that receives a setting of Post. This also goes for “put” and “delete” requests. Also, since most post operations involve the operation receiving information to be posted, the URL takes on an additional shape.

[GetOperationContract]
[WebInvoke(UriTemplate =
"/products/update_product_name.xml?
     product_name={name}",
           Method = "POST",
           BodyStyle = WebMessageBodyStyle.Bare,
           RequestFormat = WebMessageFormat.Xml,
           ResponseFormat = WebMessageFormat.Xml)]
void Update(string name);

Here you see a WCF operation that expects a string argument called name. You’ll also notice that the URL that defines how this operation will be accessed contains {name} within it. This is the section that the consumer of the URL will need to substitute with an actual value that will be passed into this operations argument.

This is about as far as I want to get into a generalized REST discussion so I don’t digress too much from Twitter. It should be enough to help you understand the fundamentals in the context in which I’ll now use them.

Meanwhile, Back in Twitter…

Twitter has already defined its API. To put this in WCF terms, Twitter has already determined what its data contracts look like. What you have to do is take that XML format and turn it into a WCF data contract in all of its splendor. The Twitter API defines some XML formats for all the data it provides and two of the more commonly used are those of a status and a user. A Twitter posting is referred to as a status, to use Twitter terms. A user enters their status and you can obtain information about both by making an API request. When requesting the public timeline, as I showed you earlier, the XML that’s returned takes the format illustrated in Figure 2.

You can see in that illustration an XML tag called status that wraps all the information about that posting using other XML tags. You’ll also notice an XML tag called User. This, of course, contains information about the user that posted that status. Each of the XML tags can map to a property of a .NET class.

Data Contracts

Using WCF terminology now, I will define the first data contract called Status whose properties will correspond to the XML tags you see within the status element.

My preferred naming convention for WCF data contracts is to end each class name with the word Data, so I’ll create a class called StatusData. If you were to map this class to the status XML element as defined in the Twitter API, you would have nine regular properties. This does not include the user element, so I’ll cover that afterwards. I’ll make the properties more user friendly by making them Pascal-cased as opposed to all lower case like the XML elements are named.

public class StatusData
{
   public string CreatedAt { get; set; }
   public string Id { get; set; }
   public string Text { get; set; }
   public string Source { get; set; }
   public string Truncated { get; set; }
   public string InReplyToStatusId { get; set; }
   public string InReplyToUserId { get; set; }
   public string Favorited { get; set; }
   public string InReplyToScreenName { get; set; }
}

Like a normal WCF data contract, I need to use the DataContract and DataMember attributes but here is where I’m going to make the mapping to the XML format defined by Twitter. Both of these attributes can define a Name argument whose value corresponds to the XML into which the data contract will map. If you refer back to Figure 2, you’ll see that the XML elements correspond to the following values for the Name argument. Listing 1 shows the final code for the StatusData data contract. Note that even the class name is mapped to a different name using the DataContract attribute since this is the wrapping element name defined by Twitter.

I’ve also told the data contract the specific order that it should expect to find the elements by making use of the 0-based Order argument.

What I’ve done here is a little different from what many seasoned WCF developers might be used to. I’m defining WCF data contracts for an XML format that has been defined by somebody else. But if you think about it, when you use Visual Studio to add a service reference to an existing WCF service, it essentially does the same thing. Adding a service reference causes Visual Studio to create data and service contracts for the service to which you point it.

One item of importance here is the fact that I declared all of the data contract’s members as strings. The reason for this is that even though the XML to which they’ll map contains numbers as well as Booleans, I can’t depend on that data being 100% valid every single time. Indeed, I’ve used this API where a field that is set to true or false in many occasions was empty in some. This will cause a serialization exception to occur when I make the WCF call, so by declaring all the fields as strings, I ensure that I can accommodate any value that it finds. Ideally, I should expose this in a more intelligent way in a product quality API so I’ll touch on that topic later.

I need to define a second data contract to represent a group of StatusData objects. Normally, groups of a single data contract are represented in a WCF conventional SOAP message by being surrounded by an XML tag named “ArrayOf{contract}”. The Twitter XML format does not follow this convention, and I need to account for this. Luckily, the System.Runtime.Serialization namespace where the DataContract resides also contains a little known attribute called CollectionDataContract. This attribute is great for creating a data contract to represent a collection of other data contracts and have complete control over the mapped name in the corresponding XML. I’m going to create a class called StatusesData which will inherit from a generic list of StatusData objects, then use this attribute to mark it as a data contract and give it the mapping names for both the collection of elements itself, as well as the element name which it will be collecting.

[CollectionDataContract(Name = "statuses",
      ItemName = "status")]
public class StatusesData : List<StatusData>
{
}

Refer to Figure 2 and you’ll see the statuses and status elements in use. My StatusesData class doesn’t need any additional contents since inheriting from the generic collection will suffice. Remember, WCF automatically performs the necessary conversion from a CLR-specific generic list to an industry-standard array of elements.

Service Contracts

Now that I have a data contract, I have to create a service contract. The Twitter API documentation defines various XML formats, one of which I’ve already discussed. It calls this one the “Status” format and shows you several REST URLs that return XML data in this format. It also shows you REST URLs that return data in a few other formats. I’m going to group all the REST URLs that act upon a given XML layout together and make that my definition for a WCF service contract. For example, the Twitter API documentation lists the following REST URLs that return or act upon the “Status” XML format:

  • /statuses/user_timeline/{screenName}.xml
  • /statuses/public_timeline.xml
  • /statuses/friends_timeline.xml
  • /statuses/show/{id}.xml
  • /statuses/replies.xml
  • /statuses/update.xml?status={text}
  • /statuses/destroy/{id}.xml

I’m going to create a service contract called ITwitterStatus that defines methods that represent each of these URLs.

[ServiceContract]
public interface ITwitterStatus
{
    [OperationContract]
    StatusesData GetUserTimeLine(
       string screenName);
    
    [OperationContract]
    StatusesData GetPublicTimeLine();
    
    [OperationContract]
    StatusesData GetFriendsTimeLine();
    
    [OperationContract]
    StatusData GetStatusById(string id);
    
    [OperationContract]
    StatusesData GetReplies();
    
    [OperationContract]
    StatusData Update(string text,
                      string inReplyTo);
    
    [OperationContract]
    StatusData Delete(string id);
}

I’ve designed this like a conventional WCF service contract but that’s not going to be enough. In order for me to use these operations in a REST fashion, I have to decorate each one with the WebGet or WebInvoke attribute. As in the example I showed you earlier, this is where I’ll map the URL to the method. Listing 2 shows the final ITwitterStatus service contract. Note the operations that receive arguments; you’ll see the same argument name used within the defined URL within a set of curly braces. This goes for both operations that request information as well as those which post information, such as the Update and Delete operations.

I’m not going to be writing any services that implement this contract because in this case, I’m going to be the consumer. However, I do need some kind of WCF proxy. In fact, the kind of proxy I’m going to write is a quintessential WCF proxy class. Like any other, it will inherit from ClientBase<T> with T being the service contract, and it will implement the service contract in order to obtain the operations. Like any other WCF proxy class, each operation method will simply make a call out to the corresponding method in the Channel base properties. You can see the proxy class in Listing 3.

I have all the code I need so far to access Twitter information using any of the URLs I listed earlier. However, like all conventional WCF usage, I need some configuration code. And of course, configuration will go at the client level.

Configuration

All the code I’ve written so far is housed in a single project in the downloadable code that accompanies this article. This single project also serves as the test client. Of course, for developing a production quality API you would separate these two things.

The configuration I’ll need in my application is, for the most part, conventional WCF configuration for a WCF consumer. This means that it will all be encased in <client> tags within <system.serviceModel> tags.

The <client> section will contain one or more endpoints just as if I was consuming a conventional WCF service, but there are a couple of differences about this endpoint with which you may not be familiar. Like any other endpoint, it will contain the ABCs of WCF: an address, a binding, and a contract.

Remember that in the service contract I created, I decorated every operation with either the WebGet or WebInvoke attributes, both of which defined a URI to access the REST operation. What I need to give the endpoint now is the first part of that URI in the form of a base URL. Earlier I describe a sample Twitter API call using a URL that started with the Twitter domain address and that’s the address I will use in all of my endpoints, http://www.twitter.com.

The binding I need to use is one that you probably haven’t seen in conventional HTTP or TCP-based WCF usage, and is called webHttpBinding. You use this binding for endpoints that access services exposed through HTTP request instead of SOAP messages. Such is the case with REST.

I will configure the ITwitterStatus contract I defined earlier. This part is just like any WCF usage you’ve seen in the past.

Obviously as I create more service contracts, I will have to define an endpoint for each one, but setting up the endpoints is not enough. I need to define an endpoint behavior with a single tag defined within it. This tag, called <webHttp/>, is used in conjunction with the webHttpBinding binding and enables the Web programming model for a service. The endpoint then needs to use the behavior by employing its behaviorConfiguration attribute.

The snippet below shows the configuration as I’ve just described it:

<system.serviceModel>
  <client>
    <endpoint address="http://www.twitter.com"
              binding="webHttpBinding"
              contract="TwitKit.ITwitterStatus"
              behaviorConfiguration="twitter"/>
  </client>
  <behaviors>
    <endpointBehaviors>
      <behavior name="twitter">
        <webHttp />
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

With what I have so far, I’m ready to access the API. This is absolutely no different than the consumption of any other service using WCF client technology. All I have to do is instantiate my proxy class and call upon any of its methods, returning the appropriate data contract class. In the code download, I even bind the returned results right to a DataGridView control like this:

using(TwitterStatusClient proxy =
      new TwitterStatusClient())
{
    StatusesData feed = proxy.GetPublicTimeLine();
    grdResults.DataSource = feed;
}

Think I’m done? Absolutely not, and as the Mythbusters say, “What’s worth doing is worth overdoing.” OK, maybe not overdoing, but there are a few levels you have to take this to. First of all, several of the exposed API calls from Twitter require authentication on your part. For example, to access your friends’ timeline, Twitter will need to know who you are. For this you need to give WCF some security credentials.

Security

Security, in the context of WCF, is probably one of the more complex topics you’ll run into. There are many combinations of settings available for all types of scenarios. Then there’s the topic of certificates which makes many people cringe. Luckily, I’m just accessing Twitter in the context of a client so my security is going to be much simpler.

In the Config File

WCF security is typically set up in the configuration section, but of course as with any other WCF configuration, it can also be done programmatically. You do all WCF security configuration by configuring the binding used on an endpoint. The endpoint I defined earlier uses the webHttpBinding binding so I now need to create a binding configuration section for that binding. I’ll do this in the <bindings> section inside the <system.serviceModel> section like this:

<bindings>
  <webHttpBinding>
    <binding name="secureTwitter">
    
    </binding>
  </webHttpBinding>
</bindings>

This configuration code implies that I can have several configurations for the webHttpBinding as long as I give them each a unique name. I’ll address this name later from the endpoint.

The first setting in my binding configuration will be the mode used for WCF security. The mode used for accessing Twitter will be TransportCredentialOnly. The two other options available here are Transport and None. Setting my security mode to None will eliminate all security which is obviously not what you need here. A setting of Transport will expect a pre-defined trust relationship between my client and the Twitter servers. The TransportCredentialOnly mode passes the user credentials through the transport layer without encrypting or signing the message.

The final configuration entry will tell WCF to use a Basic value for its client credential type, meaning the service on the other side is expecting to receive authentication credentials for any call that requires them at all points in time. The complete binding configuration looks like this:

<bindings>
  <webHttpBinding>
    <binding name="secureTwitter">
      <security mode=" TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </webHttpBinding>
</bindings>

Now that I have a binding configuration defined, I have to assign it to an endpoint. The problem is that once I have an endpoint using this configuration, it will expect authentication credentials no matter what the call is going to do. And remember, some of the Twitter API calls do not require authentication.

For this reason, I’m going to create an additional endpoint that will use this configuration and leave the first one alone. An endpoint points to a binding configuration by employing its bindingConfiguration attribute and settings its value to the name I gave the binding configuration.

Once I have more than one endpoint, I need to name them so I’m going to call one of them unsecure and the other secure. Listing 4 shows the final configuration section.

The last thing I need to do now is to pass credentials into the proxy object that my client code is instantiating.

In the Proxy

It’s a pretty common practice that a WCF proxy class has a non-default constructor that receives the name of an endpoint, and then passes that name to the proxy’s base constructor. Any authentication credentials also need to be set in the proxy’s ClientCredentials property as defined in its base class, ClientBase. For my example, I’m not going to have a constructor that receives an endpoint name but I am going to have two constructors.

A default constructor will send the endpoint name “unsecure” to the ClientBase class, while a non-default constructor will pass the endpoint name “secure” to the base class. The non-default constructor will receive the authentication credentials as arguments and use them to set the ClientCredentials property.

This solution will allow me to send any authentication credentials to the proxy directly from the client code, and also not worry about endpoint names. The new constructors for the TwitterStatusClient class look as follows:

public TwitterStatusClient() : base("unsecure")
{
}
    
public TwitterStatusClient(
    string userName, string password)
    : base("secure")
{
            this.ClientCredentials.UserName
             .UserName = userName;
            this.ClientCredentials.UserName
             .Password = password;
}

Now to use the proxy from the client for an operation that will require authentication credentials, I can perform the following:

using (TwitterStatusClient proxy =
   new TwitterStatusClient(
   "miguelcastro67", "keepdreaming"))
{
    StatusesData feed =
       proxy.GetFriendsTimeLine();
    grdResults.DataSource = feed;
}

The Twitter API documentation mentions which API calls require authentication and which do not. Your client applications would need to use the right constructor on a proxy class depending on what kind of call you want to make. Of course, the safe thing is to simply always use the constructor that expects the authentication credentials. Suffice it to say that attempting to use an operation that requires authentication by using a proxy class without credentials would raise an exception.

Everything I’ve demonstrated thus far sets the groundwork for continuing to develop a simple or even complex WCF-based Twitter library. I’m going to build on everything I just went over and continue my WCF-based Twitter library.

Continuing the API

The Twitter API documentation clearly lists out every REST-based URL that it exposes and illustrates all of the XML files that they return. If I want to write a complete WCF-based Twitter library, I can map all of these to WCF data and service contracts.

The Next Contract-Users

I showed you earlier the XML that’s returned when I execute one of the REST requests from a browser (Figure 2). If you look closely at that illustration, you’ll notice that it contains a group of statuses and all the status properties have already been represented in my StatusData data contract.

An additional set of data that each status contains, and that is shown in the illustration, is user information. Every status contains information, 25 fields to be exact, about the user that posted it. This information is in the <user> tag that is the last field of each <status> tag. On the flip side, there are API calls that return user information as its primary information. For example, type the following into a browser:

http://www.twitter.com/
                 statuses/followers.xml

This REST command will first attempt to authenticate you, and then if successful it will return a list of your Twitter followers. The XML returned starts with the 25 user fields. The 26th field is one of type <status> and contains the current status for that user.

So what you see here is some status information and some user information. In some cases, the user information is a subset of each status and others the status information is a subset of each user. The StatusData WCF data contract I created and used earlier is therefore incomplete because it doesn’t include user data-time to fix this.

First, I’ll create a UserData data contract (Listing 5). This data contract represents all of the XML fields defined within the <user> tag. As in the case of the StatusesData class, I also want to create a collection class called UsersData, which will simply look like this:

[CollectionDataContract(Name = "users",
       ItemName = "user", Namespace = "")]
public class UsersData : List<UserFeed>
{
}

Do you notice something different here? This class inherits from a list of UserFeed classes, not UserData classes. I haven’t written the UserFeed class so I’ll do that now, but first let me explain why I need it. The UserData contract only contains information represented within the <user> tags in the defined XML layout from the Twitter API. This layout, however, is used in two different scenarios. In one scenario, when retrieving status timelines, it appears within each status. In a scenario retrieving user information, it itself contains a status within. I want to be able to use the UserData contract in both situations but I don’t want to include the StatusData class as a property of the UserData class or in one of the scenarios since I’d be defining an infinite recursion. The UserFeed class will then inherit from UserData and add a single property of type StatusData like this:

[DataContract(Name = "user", Namespace = "")]
public class UserFeed : UserData
{
    [DataMember(Name = "status", Order = 25)]
    public StatusData Status { get; set; }
}

Now I can write my ITwitterUser service contract, whose methods will return either a UsersData collection contract or a UserFeed contract. You can see the complete service contract in Listing 6. I’ll take care of the client proxy a little later. Right now I need to go back and make a similar modification to the StatusData class.

Enhancing the Status Contracts

The StatusData data contract that is used by the ITwitterStatus service contract will also be used in two similar scenarios; one where it will contain a UserData contract, and another where it will be contained within a UserFeed contract.

Following the same pattern, I’ll create a StatusFeed class that will inherit from StatusData and add a property of type UserData.

[DataContract(Name = "status", Namespace = "")]
public class StatusFeed : StatusData
{
    [DataMember(Name = "user", Order = 9)]
    public UserData User { get; set; }
}

Now both the StatusFeed and UserFeed data contracts contain respectively the UserData and StatusData classes and we don’t run any recursion risk.

The last change I’ll need to make to existing code is to modify the StatusesData class to inherit from a list of StatusFeed classes.

[CollectionDataContract(Name = "statuses",
     ItemName = "status", Namespace = "")]
public class StatusesData : List<StatusFeed>
{
}

I also to change the operations in the ITwitterStatus service contract that returned a StatusData class to return a StatusFeed class instead. The same applies for my TwitterStatusClient proxy class since it implemented the ITwitterStatus interface. Listing 7 shows the modified service contract and proxy.

The ITwitterUser service contract is going to need a proxy class that I’ll use to access its operations. This would look just like the TwitterStatusClient proxy class and would be called TwitterUserClient. You can see this class in Listing 8. Notice that because some operations may require authentication, I’ve provided that class with the same two types of constructors as the TwitterStatusClient class.

The last thing I need to do is add entries in the configuration file to accommodate endpoints for the ITwitterUser service contract. This will look exactly like the endpoints for the ITwitterStatus service contract but of course pointing at a different interface, like this:

<endpoint address="http://www.twitter.com"
          binding="webHttpBinding"
          contract="TwitterWcf.ITwitterUser"
          behaviorConfiguration="twitter"
          name="unsecure" />
<endpoint address="http://www.twitter.com"
          binding="webHttpBinding"
          contract="TwitterWcf.ITwitterUser"
          behaviorConfiguration="twitter"
          bindingConfiguration="secureTwitter"
          name="secure" />

Additional Configuration

There will be cases where some of the calls you make will return a message that exceeds the default 64K WCF message size. To make sure I can accommodate larger messages, I want to add a setting in my binding configuration to extend the message size. The problem is that the only endpoints that are using my custom binding configuration are the secure ones. For this reason, I need to create another binding configuration that simply extends the message size and also add the same setting to the existing binding configuration.

<bindings>
  <webHttpBinding>
    <binding name="secureTwitter"
        maxReceivedMessageSize="1000000">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
    <binding name="unsecureTwitter"
        maxReceivedMessageSize="1000000">
    </binding>
  </webHttpBinding>
</bindings>

Now I have to make sure all my endpoints address one or the other. Listing 9 shows the complete config file.

Other Contracts (Your Homework)

The Twitter API documentation defines other XML layouts and groups of operations that can be directly translated into WCF data contracts and service contracts. I won’t develop them in this article but I’ll talk about a couple of them.

Direct Messages

Another type of posting you can make with Twitter is in the form of a direct message to one of the users that’s following you. Twitter defines an XML format for a direct message that you can see by accessing one of the API calls from a browser. One possible call is as follows:

http://www.twitter.com/direct_messages.xml

The XML returned by this URL includes a few fields to describe the message, but it also includes an XML tag called <sender> and one called <recipient>, both of which follow the layout of the <user> tag I’ve talked so much about.

A WCF data contract that maps to this layout needs to define the fields in the XML and also include two properties of type UserData. Such a data contract is shown in Listing 10.

Now I need a service contract to house operations that act upon the DirectMessage data contract. I can certainly create one massive service contract and put every single operation I need in there, but in the interest of organization, I prefer to group my service contracts according to the groupings that the Twitter API documentation illustrates. These groupings would then merit the creation of an ITwitterDirectMessage service contract to contain my direct message operations. And of course I would then need a TwitterDirectMessageClient proxy class as well.

Other types of operations that should be grouped together include those acting upon Twitter Replies, Favorites, and Friendships. Also, remember that every service contract you write is going to need the two endpoints in the configuration file.

Abstracting WCF

At this point, you should have enough information to build a pretty decent Twitter library using the state-of-the-art technology, WCF. You should also have a pretty good understanding of using REST with WCF. One thing I want to leave you with is the fact that I may want to eliminate the necessity of having WCF skills from the developers using my Twitter library.

Eliminating Configuration

The first step toward doing this is to eliminate the need for the client developer to have to add WCF configuration to their configuration file. To do this, I have to change the approach to how my client will obtain a proxy class. Up to now, I’ve created a proxy class for each WCF service contract I have. What I’m going to do now is to create a proxy factory class that will create a proxy for me using the WCF channel factory and also provide the channel factory with the entire configuration necessary.

My proxy factory class will be a static class with only two static methods. Both methods will be called GetProxy and will receive the service contract type in a generic argument, and thus return that type. The signature difference in the two methods will be that one of them will receive the authentication credentials as arguments.

public static T GetProxy<T>() where T : class
  {
  }
    
public static T GetProxy<T>(string userName,
string password) where T : class
  {
  }

Notice that there’s a class-restriction on the generic argument. This is because later, the channel factory that I’m going to use will fault if it thinks that T can be anything at all.

The task of each of these methods is similar. First, I’ll create a binding object to represent the WebHttpBinding I used earlier and set any configuration settings I need. These were expressed in a binding configuration when I was using the config file.

WebHttpBinding binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = 1000000;

I’ll use one of the GetProxy methods to obtain a secure proxy so it will need a little more programmatic configuration.

WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode =
  WebHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType =
  HttpClientCredentialType.Basic;
binding.MaxReceivedMessageSize = 1000000;

Notice all of these settings resemble what I did earlier using configuration information. Next, I have to obtain a proxy class that will contain all the operations I’m looking for, so of course, the type of the proxy I need will be the type of the service contract in question.

WebChannelFactory<T> factory =
  new WebChannelFactory<T>(
    binding, new Uri(TWITTER_URL));

Because I’m using REST, I need to use the WebChannelFactory class and not the conventional ChannelFactory class that I would use if this was traditional WCF usage. The generic argument received in the GetProxy method is passed into the channel factory. Also, the TWITTER_URL constant is just a variable that is set to http://www.twitter.com.

In the version of GetProxy that receives the authentication credentials, I need to do a bit more. Now that I have a factory that I will soon use to obtain a proxy object, I need to feed that factory the credentials passed into the method.

ClientCredentials credentials =
   factory.Credentials;
credentials.UserName.UserName = userName;
credentials.UserName.Password = password;

Now I can use the factory object to obtain a proxy that will be of type T, and remember that T is the type of the service contract whose operations I need to use.

T proxy = factory.CreateChannel();

Now I can simply return the proxy object through the method. You can see the complete TwitterFactory class in Listing 11.

There’s one additional line in the listing that I haven’t explained. Some time ago, Twitter made an update in their servers and many .NET client applications started returning 417 errors when making some calls. It seems that .NET automatically includes an “Expect” header containing “100-continue” on every request. This has to do with the way header and form information is sent to a server during an Http request. In any case, for accessing the Twitter API you have to tell .NET not to do this so I have to make an additional setting:

ServicePointManager.Expect100Continue = false;

In the Good Info Links sidebar, I’m including a link to Phil Haack’s blog where he talks about this in a little more detail.

Twitter’s API limits you to 100 requests per hour.

Product Quality Objects

I mentioned earlier that a production quality API should expose object members of a proper type and not all strings like my data contracts are (I also explained why I’m using all strings). In fact, if you’re writing a Twitter library using WCF, you should probably abstract all WCF-specific stuff from the developer that will use your library. My first step for this was to eliminate the need for configuration, which I did in the last topic. Another thing I want to do is to provide a nice object model wrapper for the proxy calls and for the returned data contracts. This way a client can simply instantiate a Twitter Library object, ask for information and receive in return a nicely designed object model.

Things that a more intelligent object model would do are to convert those true and false strings that are returned by the data contracts into actual Booleans. Another thing may be to expose actual .NET DateTime properties where the data contract also uses strings. If you look at the XML that Twitter returns, you’ll see that dates are not exactly in a DateTime-friendly format. There are also several fields in the data contracts that contain numeric values so these should be exposed as actual numeric CLR types. Also, a couple of fields in the UserData data contract contain color RGB codes. You can expose these using a nice Color object.

All these things are beyond the scope of this article but I’ve given you the foundation upon which to build a pretty nice Twitter library. In fact, there are several of them out there already (see Good Info Links sidebar).

I need to give you one final piece of slightly important information before I send you off into the Twitterloo Sunset (Kinks reference). The Twitter API limits you to 100 requests within any give hour. I guess this is Twitter’s way of not overburdening their servers, so who knows if this will always be the case. But as you play, you may run into this and all you can do is have a drink and wait it out.

Conclusion

I hope you’ve enjoyed this little adventure into the Twitter API and WCF-REST. I thought that this would be an enjoyable way of getting exposed to REST in WCF at the same time, as well as learn an API of what is now one of the more popular social networking sites out there. All things considered, people use Twitter in more and in many unconventional ways. It also seems to be relied upon as a means of unconventional communication in quite extreme situations. As I write this article, Twitter decided to suspend an update installation so they don’t interrupt all of the Twittering that is coming from Iran at the moment. It appears that many around the world are obtaining inside information about what is going on with the Iranian election situation by accessing Twitter feeds. Incorporating WCF into this is a great way to stay completely state-of-the-art in the technology you use to access Twitter information.

Happy Twittering, and have a good REST.