Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Facebook Integration via Hammock

4.82/5 (10 votes)
10 Jul 2011CPOL5 min read 39.7K   1.5K  
Recently I made the distinction between frameworks where community driven libraries thrive, and evolving APIs where they often become the kiss of death. In this article I want to give an example of integrating with Facebook using the REST library Hammock.

Introduction

Recently, I wrote about Social Media and strategies for integration. I intentionally didn't go into detail as I wanted to take a more philosophical view on our development processes. I made the distinction between frameworks where community driven libraries thrive, and evolving APIs where they often become the kiss of death for projects.

I believe we need to change the way we work with Social Media APIs and stop trying to create SDKs for these APIs in the technology of our choice. The technologies evolve too quickly and instead we need to embrace the core technologies, whilst keeping the integration layers lightweight.

In this article, I want to give an example of one approach by demonstrating some integration with Facebook. The key point here is that rather than using one of the many .NET libraries which wrap Facebook APIs, I'm instead using a generic library that is entirely decoupled from the Facebook APIs themselves.

Hammock - REST, Easy

Hammock is an open source project built in .NET which facilitates the consumption of RESTFul services in a generic way. It offers support for asynchronous operation, query caching, mocking, and rate limiting among other features. There are of course other libraries which could equally be used.

The Code

The following shows an example of retrieving posts from a user's wall in ASP.NET. We could achieve the same functionality through JavaScript alone, but let's assume we want to do something with the data on the server. This requires that the user has granted the read_stream permission to the Facebook application and assumes the user is authenticated. In the source code provided, I've shown how to achieve both of these tasks using Social Plugins and JavaScript with minimal effort.

The first thing we need to do is create an instance of Hammock's RestClient class. This contains the base URI of the service EndPoint and can also contain other default properties such as a UserAgent string.

C#
IRestClient client = new RestClient
{
 Authority = "https://graph.facebook.com/",
 UserAgent = "MyFacebookApp"
};

Next we create an instance of Hammock's RestRequest class. This allows us to make RESTFul calls to a particular path relative to the base EndPoint URI defined above. Using Hammock's API it's then simple to add request parameters to the call. In this case, the user's access_token is appended to the querystring to provide the required authorization.

C#
// call https://graph.facebook.com/[userid]/feed
var request = new RestRequest
{
 Path = string.Concat(UserId, "/feed"),
 Method = WebMethod.Get
};
request.AddParameter("access_token", AccessToken);

Note the UserId and AccessToken values shown in the sample above are obtained from the currently authenticated Facebook user. In the source code provided, I'm passing these values from an Ajax call triggered by a Social Plugin login event.

OK so far it's easy right? Any changes to the Facebook API means we can quickly add or remove parameters that are sent to the API.

The next step is to make the request and parse the response. This is done using the RestClient we created earlier.

C#
var response = client.Request(request);

// check for errors and do something
if (response.StatusCode != HttpStatusCode.OK)
{
 throw new CommunicationException(
  string.Format("The EndPoint {0}{1} returned an unexpected StatusCode {2}",
  client.Authority, client.Path, response.StatusCode));
}

// this is the raw JSON response
var content = response.Content;

OK, so now the interesting bit, and this is where I come back to my point about keeping this lightweight and loosely coupled. We could use Hammock's deserializer to type the response directly to our own object, but that's too rigid for my liking. Instead I want to use the dynamic type. This will allow us to access the JSON properties in a loose fashion which can more easily be changed if the API is updated.

Now I couldn't figure out how to get Hammock's out-of-box deserialization to work with dynamic objects. It may be possible, and if anyone knows, please let me know. Instead I created my own JavaScriptConverter extension so I can use .NETs in-built JavaScriptSerializer class. You could also register your own custom deserialization classes via Hammock's interfaces but I've kept it simple.

C#
// set up deserialization classes
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new JsonConverter() });

// deserialize the raw JSON
dynamic result = serializer.Deserialize<ExpandoObject>(response.Content);

// parse the results 
foreach (dynamic obj in result.data)
{
 Response.Write(obj.from.name + " wrote " + obj.message);
}

Static vs Dynamic Typing

The nice thing about ExpandoObject is that not only does it provide dynamic access to the response object to keep it loosely coupled, but it also implements IDictionary<string, object>. This means it can easily be converted to a typed object using JavaScriptSerializer. This is useful if we decide to move the code into a service layer and want to provide a strong typed model to our business layer. Only properties that are defined on both source and target will be mapped across in the conversion, other properties are simply ignored.

C#
// define a class for post content
public class Post
{
 public string Id { get; set; }
 public string Message { get; set; }
}

foreach (var obj in result.data)
{
 // convert ExpandoObject to the Post class
 var post = serializer.ConvertToType<Post>(obj);

 // we now have strong typed access to content
 var message = post.Message;
}

Running The Demo

To run the demo code included, you should replace the Facebook AppId in value FBHelper class with your own Facebook application key. See Facebook documentation for more details on how to obtain this.

You will notice in the source code provided that I've created a custom expando class called JsonExpandoObject. This is because ExpandoObject throws exceptions if you try to access a property that doesn't exist. My version returns null instead and therefore works much better with JSON.

Summary

So to summarize, generic third party libraries such as Hammock can be used to speed integration with Social Media APIs. This has the advantage over third party Social Media SDKs in that it keeps the codebase more loosely coupled. In doing so, it allows developers to build applications around long established core technologies and produces a codebase more adaptive to change.

By implementing late binding via dynamic types, you can further decouple hard dependencies on APIs. This is particularly useful for lightweight manipulation of content within the data layer. For passing objects to the business layer, I've shown how JavaScriptSerializer can be used to quickly convert dynamic types into static types as required.

Static types are of course checked at compile time and offer many advantages over dynamic types. The trick here is that we are able to leverage static types in our business layer, but map/convert from objects which are late-bound to API code. This mapping/conversion code becomes the single touch point for maintenance when APIs change.

The example included also shows how we can leverage the emerging Social Plugins and JavaScript APIs which are more resilient to change. These can be used for core functionality and should always be favoured where possible.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)