Web API: HTTP Restful Endpoints, The WCF Way   3 comments

Part I: Overview and Serialization (this post)

Part II: WCF Endpoints

Part III: Implementing WCF EndPoints

Restful HTTP Endpoints

I love QCON, the technical web conference sponsored by InfoQ.  This year I attended the conference in San Francisco.  Some nice things about QCON is that it is not a a trade conference for a major powerhouse like Microsoft or Google.  Although I am a regular attendee of Microsoft’s MIX conferences, but there is something to be said for QCON focus on emergent web technologies and its focus on ideas and not products. My conference report is can be found here. This year I attended the tutorial “REST in Practice” which was presented by the authors of the book “REST in Practice”, Ian Robinson & Jim Webber.  The presenters and the audience were very well informed on both the web in the real world and the minutia of HTTP programming.  For a nerd like me (NLM), nothing is more fun than getting into  the finer points of a Fiddler dump. Untitled picture One thing bumping around QCON this year was the topic “WEB API”, what in the world I though was a WEB API.  Don’t be unhip like me, what is meant by a WEB API is exposing a full API for a distinct system solely through a coordinated set of RESTful HTTP endpoints (think Netflix and Flickr).  Somehow this wants to be a TLA like WEP (Web End Point but WEP is already taken).  This is the concept of AJAX matured into a true systematic technology.   In my day job I work on the development of secure Web Portals, armed with the background provided by the tutorials and sessions at QCON I returned to work resolved to cleanup our HTTP end points.  A couple of references may help.  On RESTful development see the Richardson Maturity Model and the InfoQ classic: How To GET a Cup Of Coffee.

WCF: The Microsoft Connection

I work in a Microsoft shop and so the Microsoft’s WCF is the tool of choice to develop HTTP Endpoints.  Because of our particular product goals HTTP Get’s provide the bulk of our services.  Starting with Framework 3.5, WCF has provided a rich set of tools to create RESTful dynamic HTTP Endpoints.   I started out programming XML Web Service for intra-server communication.  Although this is a very mature and powerful technology it is not optimized for Browser to Server communication, particularly  Javascript is difficult to use to develop Web Service proxies (although it can be done) and XML is rarely the tool of choice to communicate object graphs to Javascript, JSON is preferred for this purpose.  WCF For Rest (see this and this reference).  Here is a chart I developed from my notes during QCON comparing Web Services, REST and WCF for Rest:

Web Service Standard REST Service WCF For REST (Framework 3.5)
1 TCP/IP + others TCP/IP TCP/IP
2 SOAP Wrapper HTTP HTTP
3 SOAP Headers HTTP Headers HTTP Headers
4 WS*Security Basic Auth/SSL Basic Auth/SSL or WS*Security
5 Early Binding Late Binding Late Binding
6 XSD WADL XSD
7 XML Media Negotiation Media Negotiation
8 SOAP FAULTS HTTP Response Codes HTTP Response Codes
9 Single Endpoint Multiple Endpoints, URI Templates Multiple Endpoints, URI Templates
10 Client Proxy Custom auto-generated Javascript proxy

The core text I used in developing WCF for Rest is the excellent and insightful RESTful .NET by Jon Flanders (see also and Jon’s Blog).

What We Are Trying to Achieve: The Problem Domain

In this blog post we will focus on a limited problem I need to solve.  Here is the overview of the problem.  At fixed points in time our code needs to collect a complex set of information on a particular subject (i.e. a graph) and persist that information for later recall. At irregular times browsers will request sub sets of the information in JSON format. The data object is quite complex.  Entity Framework would happily generate the hundreds (thousands?) of lines of code to persist and retrieve the data from a SQL database but this task cries out for a key value store (like couchDB ) so rather than looking at:

Picture2

We can have something like:

Untitled picture2Where User_Id and Date are meta data fields for the object graph represented in the column AlertsUser.  This seems like a good start, before developing the actual HTTP Endpoint we need to deal with serialization issues.  How and in what format to serialize the C# object into a nvarchar column in the database, how to desterilize that data back into a C# object and then to serialize the object into JSON for delivery to the user.  Note that in some use cases you could simplify this to:  Object serialized to JSON; and then inserted into the database  and then retrieved and passed directly to the caller.  In our use case however a single HTTP Get will request one or more rows from the data base so we require the more complex: Object serialized to nvarchar compatible object then deserialized into an array of C# object and then serialized into a JSON array.  In this use case we will use XML as our format for storing data into the database, so we have

Object –> database rows of XML in string format

XML rows – > An Array of C# Objects

Array of C# Object –> JSON Array.

In the next section of this post I will cover how to do this using C# and when this is accomplished I will in the subsequent section turn to how I developed a generic HTTP Get endpoint to serialize the data into JSON and return data in that representation to the browser.

Serialization: Objects &  XML

For purposes of this post lets define a basic C# object which we want to work with.  Here is a minimal object for serialization:

    public class CObject{
public string ID { get; set; }
public string Name { get; set; }
public List<string> Data { get; set; }
public CObject( ){
Data = new List<string>( );
}
}


Note that I have defined an an explicit class initializer. If you are going to be doing serialization a parameterless initializer is required.  To make fields available for WCF type serialization we need to add attributes: DataContract and DataMember.  Use the DataMember attribute to identify those fields you whish to serialize.

    [DataContract]
    public class CObject{
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public List<string> Data { get; set; }
public CObject( ){
Data = new List<string>( );
}
}

For XML serialization we may further shape the XML by using the XML attributes as follows:

XmlRoot                                            Defines The XML Namespace used by the object

XmlElement                                     Causes the XML serializer to output a field as an element and optionally names the element

XmlAttribute                                   Causes the XML serializer to output a field as an attribute to the enclosing element and optionally names the attribute

XmlArray and XmlArrayItem             Names The Root Element of an Array and separately the names of each array member

Our full adorned object might then look like:

    [DataContract]
[XmlRoot(Namespace=”
http://cloud2013/2012/01/”)]
    public class CObject{
[DataMember]
[XmlElement(“Key”)]
public string ID { get; set; }
[DataMember]
[XmlAttribute]
public string Name { get; set; }
[DataMember]
[XmlArray(“Points”)]
[XmlArrayItem(“Point”)]
public List<string> Data { get; set; }
public CObject( ){
Data = new List<string>( );
}
}
We can use the WCF Data Contract Serializer to serialize an object to an XML string using the generic method ToXMLString and serialize from and XML string back into a C# Object using the generic method XMLToObject as:

public class XMLMethods<T>
{
const string _NameSpaceBase=”
http://schemas.datacontract.org/2004/07/”;
       public static string ToXMLString( T myObject )
{
MemoryStream stream1 = new MemoryStream( );
DataContractSerializer ser = new DataContractSerializer( typeof( T ) );
ser.WriteObject( stream1, myObject );
return Convert.ToString( Encoding.UTF8.GetString( stream1.GetBuffer( ), 0, ( int ) stream1.Length ) );
}
public static T XMLToObject( string xmlString )
{
TextReader sr=new StringReader( xmlString );
XmlRootAttribute root=new XmlRootAttribute( typeof( T ).Name );
root.Namespace = _NameSpaceBase + typeof( T ).Namespace;
XmlSerializer xmlSerializer = new XmlSerializer( typeof( T ), root );
return ( T ) xmlSerializer.Deserialize( sr );
}
}

calling these as:

CObject myObject=new CObject();

string xmlString=XMLMethods<CObject>.ToXMLString(myObject);

myObject=XMLMethods<CObject>.XMLToObject(xmlString);

Easy and Fun, no?

If we insert or update a SQL server column with an XML String we will need to escape the XML so we don’t run into conflicts with the string syntax of what ever SQL server type you are losing.

In my case with SQL server I need to escape single and double quote marks.  One simple way to do this, but not necessarily the fastest way,  is to 64 bit encode the string. Example code to do this is:

public static class CStaticFunctions
{
static public string EncodeTo64( string toEncode )
{
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes( toEncode );
return System.Convert.ToBase64String( toEncodeAsBytes );
}
static public string DecodeFrom64( string encodedData )
{
byte[] encodedDataAsBytes = System.Convert.FromBase64String( encodedData );
return System.Text.ASCIIEncoding.ASCII.GetString( encodedDataAsBytes );
}
}

[I have added a programmer’s note on using SQL Server as an object serialization store.  See this Post]

OK.  Enough for Part I. To be continued…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: