In This Document
RestCake is a C# library for creating REST services without WCF. WCF has many pain points: WCF is designed to be host agnostic, whereas REST implementations are very simple, and (for practical purposes) always use HTTP.
I love this quote (source):
"I'm not sure I want to build on a layer [WCF REST] designed to factor HTTP in on top of a layer that was designed to factor it out [WCF]."
All in all, WCF is overkill for REST servcies that are not going to have any other endpoints, and will not be hosted outside of IIS. All of its noble idealisms and abstractions get in the way. Let me elaborate a bit more about how WCF gets in the way.
"\/Date(1280555181054-0700)\/". Ouch! If you're using the MS Ajax runtime, sure they fix this up for you, but it's not very friendly. I've seen everything from hacks on the json2.js file to automatically fix these up to quick javascript utility methods to convert to/from this awful date format. The worst part is you don't even have a choice. RestCake uses the Json.NET serializer, which lets you choose how your dates will be formatted. The default format (ISO date format) can be parsed from its string representation directly to a javascript date, and a native javascript date can be passed to the service and deserialized into a DateTime object. More than I can say for the MS AJAX format...
Sometimes you want your service method to return a simple pair or triple of objects. With anonymous types, it's very easy to creates these kinds of tuples:
			var result = new
			{
				Person = somePerson,
				Status = Status.Success,
				NumProjects = projects.Count()
			};
		
The DataContractJsonSerializer can't serialize anonymous types, so you'd have to create a class that represents each result type that you want your service methods to return. Json.NET, on the other hand, will serialize the above object just fine.
While they have cut down the amount of configuration for WCF significantly with recent releases, there is still a lot to do. The <system.serviceModel> section in your web.config can get pretty large sometimes. RestCake doesn't require any special settings in your web.config. The REST services are based on a very simple base class, RestHttpHandler that implements the System.Web.IHttpHandler interface. Calls to your service simply go to the ProcessRequest() method of that interface, and it's all based on standard HTTP. While REST is a "high level concept", in practice it's nearly always implemented using the HTTP protocol, and a basic IHttpHandler is more than enough to get a flexible service going.

RestCake requires no configuration in your web.config. At some point there will probably be an option to specify certain global settings, but it's not required.
What's a cycle? An example would be if you had a Parent object with a List<Child> named Children. Each Child object in that list has a Parent property that refers back to the Parent. Parent.Children[0].Parent.Children[0].Parent.Children[0]....we're going in circles. That's a cycle, and because json can't represent references in an object literal, the DataContractJsonSerializer throws an exception when it encounters a cycle in your object graph. While that's very noble and idealistic, it's not very practical. Json.NET gives you many different options on how to deal with cycles, the easiest being to simply ignore them. In the example case, the Parent object would have a list of child objects, but those child objects would not have a reference back to the parent. For most people's usage scenarios (getting DTO objects to your client script to update the web UI), that's just fine.
There may be someway to easily handle all errors in your WCF service methods, but I certainly haven't found it. I'm really tired of creating FaultException<ArgumentException> objects. Really? An exception type that takes another exception type as a generic type parameter? Oh, and when you create that, you end up having to repeat all your string messages twice. Very fun. You can forget about Application_Error() in your Global.asax too. Doesn't fire when an error occurs in your WCF service method. But guess what! It does fire when an error occurs in an IHttpHandler! The RestHttpHandler in RestCake is based off of the simple IHttpHandler interface, and handling uncaught exceptions is a breeze. Once again, WCF's noble host agnosticism has made something that should be easy, quite difficult.
Any variables in your UriTemplate that are part of the Uri and not the query string, have to have matching parameters in your service method, and the type has to be string. It's can't be any of the other primitive data types. So in your service methods, you end up doing a lot of validation and TryParsing, which is not fun. It gets in the way and creates noise.
By not "sane" I mean you don't get what you want 99% of the time. A bit of code is the easiest way to explain this one. This outputs: [{"Key":"Fname","Value":"Sam"},{"Key":"Lname","Value":"Meacham"}]. What? Oh, it's a collection of (key,value) pairs. How noble! Yes, it will work if I use something totally unreasonable as a key value, such as "#$%^&", but that would be stupid, and I wouldn't do it.

Let's take a look at how Json.NET serializes that dictionary: In addition to the actual serialization being much, much easier, the result is sane! {""Fname":"Sam","Lname":"Meacham"}. Just what I wanted. Now, if for some reason I need the other behavior, a list of (key,value) pairs, it's easy enough: So we get what we want 99% of the time with the default behavior, and write 1 extra line of effort when we want the 1% of the time behavior. Where with WCF, you get what you don't want 99% of the time, and since it can't serialize anything sane, you have to write a bunch of javascript code to "fix up" the dictionaries you get back from your services. And it's a LOT of extra effort. Especially when you have to "reverse fix up" the values before you send them back to your services. Ouch.
This is a strange one, and a bit trivial, but it's very annoying. I like immutable types. Not having to deal with state change is a good thing, especially when you want to start doing a lot of parallel processing. Immutable types are immune to side effects. They don't require having locks taken out on them. Et cetera et cetera. Consider this simple immutable type: Trying to serialize or deserialize an object of type Person with the DataContractJsonSerializer will result in a runtime exception, because the [DataMember] properties don't have setters. While it does work if you have private setters, your type isn't really immutable then, is it? You can't have automatic properties that are based on readonly backing fields. The solution is to put the [DataMember] attributes on your backing fields (m_id and m_name in this case), but then you have to do this: Very annoying. And not refactor safe. Once again, Json.NET has none of these problems. In fact, your types don't need any special attributes at all.

Enough hating on WCF REST! What is RestCake?

Let's take a look at a very basic WCF REST service. Now, to get JSON, you'd either have to specify the WebMessageFormat in the WebGet attribute, or specify that you want the default to be JSON in your web.config, somewhere in the <system.serviceModel> section. That's not a bad thing, it's just something you have to remember to do, or you'll get XML back (hint: I'm not a huge fan of XML).

To access that service, you've got quite a few options. You can create a .svc file that specifies what host factory you want to use, and then navigate to that .svc file in your browser. Or, you can ditch the .svc file, and set up some ServiceRoutes in your Global.asax file, using the WebServiceHostFactory. That last option is the best, because you get clean urls.

Let's see how we'd create this same service with RestCake. Do you see the difference? It's subtle! This HelloWorldService class inherits from RestHttpHandler, and that is the only difference. You don't even need a .ashx file for your IHttpHandler, though you can certainly use one if you want. If you have a .ashx file, you can just navigate right to it to use your service. If you don't, you can set up a GenericHandlerRoute (part of RestCake) in your Global.asax, like this: RestCake uses the existing WCF attributes to figure everything out. It's based on the same UriTemplate processing. When this service is called for the first time, The RestHttpHandler base class will collect some metadata on all of the service methods in the service class. ProcessRequest() will figure out which method needs to be called, and call it with the parameter values that came with your service call (from the UriTemplate, the query string, or the POST, PUT, or DELETE data, either in query string or json format).

Also, with the above RestCake service, we don't need any special settings in our web.config. You navigate to the ashx file, or the url of the route you set up, and it just works.
Using the JsProxyCreator, you can either create a static javascript file from your assembly that has your services, or generate the javascript files on the fly by navigating to your service special url. The javascript file is a jquery proxy. It's based on the WCF proxy by Rick Strahl, but takes it quite a bit further. Javascript proxy classes are created to mirror each of your service classes, and you have all of your service methods ready to be called. Here's what calling that HelloWorld service would look like in client script. Very easy. Include the proxy script, create a new instance of the service proxy, providing the base url to the service, and call your method. In Visual Studio, you'll even get Intellisense for the method names, and the names of the arguments. You don't have to do any JSON.stringifying or parsing yourself, it's all wrapped up in the javascript proxy classes.
  1. Download RestCake
  2. Add the reference to your existing WCF REST services project
  3. Open up one of your [ServiceContract] classes, add the using RestCake directive, and change to class to inherit from RestHttpHandler
  4. Go to your Global.asax Application_Start(), and create a new GenericHandlerRoute<T> route with a unique url ("services/myservice")
  5. In a web page, add a <script> tag with the source pointing to "yoursite/services/myservice/_js?jquery&base=true" to include the automatic javascript proxy class
  6. Create a new service proxy: var g_svc = new MyNamespace.MyServiceProxy("/services/myservice/");
  7. Call your service methods from the javascript proxy object: g_svc.SayHello(arg1, function(){ /* success handler */ });

Once you're convinced, you can get rid of a bunch of WCF stuff in your web.config, cleaning things up a bit. You can change your service methods to have correctly typed input parameters. No more TryParsing all the strings you were passing in before. You can get rid of all the javascript code that "fixed up" the results of crappy, inflexible serialization. You can get rid of classes that you created just to create tuples of objects you wanted to return together. You can get rid of whatever crazy error handling you had to handle exceptions in your service methods. You can forget about faults altogether. Rest is fun again. As fun at eating cake.
samscode.com rest.codeplex.com loef.codeplex.com
©2010 samscode.com, Samuel Meacham