C# implementation of RESTfulie – The power of dynamic

Posted on 16. Jun, 2010 by sergiojunior in restful

With the grow of visibility that the Restfulie project achieved, we decided to implement a version for the .net plataform, and the C# language was chosen. To give developer’s the same “easy to use” feeling of the ruby implementation, the Restfulie C# team decided to use the new dynamic characteristcs of C# 4.0, that allows changing an object’s structure at runtime. Some people could think that’s a dangerous feature because of its power, while others will justify it by saying that in good hands, that power can be used to enhance our libraries.

Think about a resource representation of an order, with the following XML representation:

<order>

<date>12/26/2009 11:40</date>

<amount>300.00</amount>

<atom:link rel=”self” href=”http://www.caelum.com.br/orders/1″ xmlns:atom=”http://www.w3.org/2005/Atom”/>

<atom:link rel=”edit” href=”http://www.caelum.com.br/orders/1″ xmlns:atom=”…”/>

<atom:link rel=”payment” href=”http://www.caelum.com.br/orders’/1/pagar” xmlns:atom=”…”/>

<atom:link rel=”customer” href=”http://www.caelum.com.br/orders/1/customer” xmlns:atom=”…”/>

</order>

<order>
<date>12/26/2009 11:40</date>
<ammount>300.00</ammount>
<atom:link rel=”refresh” href=”http://www.caelum.com.br/orders/1″ xmlns:atom=”http://www.w3.org/2005/Atom”/>
<atom:link rel=”update” href=”http://www.caelum.com.br/orders/1″ xmlns:atom=”…”/>
<atom:link rel=”pay” href=”http://www.caelum.com.br/orders’/1/pagar” xmlns:atom=”…”/>
<atom:link rel=”delete” href=”http://www.caelum.com.br/orders/1″ xmlns:atom=”…”/>
<atom:link rel=”getCustomer” href=”http://www.caelum.com.br/orders/1/customer” xmlns:atom=”…”/>

</order>

The xml representation was enhanced, supporting not only data but also meta data that allows us, as clients, understand what we are capable of doing. After retrieving such a representation, it’s possible to execute any http verb with all those related resources. Of course, server acceptance of such requests might vary. To retrieve such representation of the resource through restfulie C# we need to do:

dynamic order = Restfulie.At("www.caelum.com.br/orders/1").Get();

The resemblance with its Ruby counterpart is an attempt to keep an uniform dsl between clients.

As you can see, the order variable has declared as dynamic, it makes to C# compiler ignores the type of the variable. This bring to us a lot of advantages, like for example, to access properties of the order like bellow:


Console.WriteLine(string.Format("Date's order is: {0}", order.Date));

Console.WriteLine(string.Format("The ammount order is: {0}", order.Amount))

Beyond to access properties of an order, we can follow the links, present’s in representation, by methods invocations like bellow:


order.Pay();
order.Delete();

dynamic customer = order.getCustomer();

Console.WriteLine(customer.Name);

This is very powerful as it supports some must ignore rules by default. As we can see, there is no need to define or configure anything in the client side. But how that magic happens in C#?

In Ruby any object can be modified at runtime, but in c# the things are different. To give dynamic behavior for C# objetcs, we need to extend’s a class named DynamicObject. When our class extends DynamicObject, we have the chance of modify object’s behaviour at runtime. So, when the call of order.Amount, what really happend?

Based on the XML representation, we have to get the value present on the tag. To implement this we use a trick similar to ruby’s method_missing. Let’s see the code below, wich was retrieved from the DynamicXmlResource class:


class DynamicXmlResource : DynamicObject {
private XElement xmlRepresentation;

public override bool TryGetMember(GetMemberBinder binder, out object result) {
// finding xml tag
object = XmlRepresentation.FindXMLTagWithName( binder.Name ).ReadTheValue()
return object != null;
}

}

The DynamicXmlResource extends DynamicObject and has a field wich is a XML representation of the resource (xmlRepresentation). The most interesting in that class is the method called of TryGetMember. This method intercepts any invocation to a property Get and allow us to do what we desire to do. In our case, what we did was seek for the property value in the XML,searching for a tag by the property name. Each time order.Amount is invoked, the TryGetMember method in the DynamicXmlResource will be executed instead, pretty much as in a AOP pattern.
In the same way we have TryGetMember method, we had other methods to allow us change objects behaviour. In our project we make use of the TryInvokeMember method to give support for the actions described through links in XML representation, see code below:


class DynamicXmlResource : DynamicObject {

private XElement xmlRepresentation;

public override bool TryInvokeMember(InvokeMemberBinder binder,
object[] args, out object result) {
object link = XmlRepresentation.FindRelAttributeWithName(Binder.Name).ReadTheLink();

if (link == null)

throw new ArgumentException(...);

HttpRemoteResponse response =
(HttpRemoteResponse) this.InvokeRemoteResource(value.ToString(), binder.Name);
return result != null;
}

}

The TryInvokeMember method will intercept any call to any method of the DynamicXmlResource object. We use this feature to seek in XML representation for the link wich has a relation with the name of the method invoked by the object. After found the link, we make a http request using the url retrieved from the link. At the same way, when we call order.Pay(), this call will be intercepted by TryInvokeMember wich will execute a remote invocation to the Restfulie Server.

By making use of C# features we can reproduce similar features to the Restfulie Ruby version, as shown:

Here is a example, using Restfulie Ruby:

order = Restfulie.at(“http://restfulie-test.heroku.com/orders/14”).get

puts order.customer_name

order.payment.post payment_information

And here we have the same example using Restfulie C#:

dynamic order = Restfulie.At(“http://restfulie-test.heroku.com/orders/14.xml”).Get();

Console.WriteLine(order.GetCustomer().name);

order.Payment(payment_information)

One of the trade-off’s of using dynamic types is the lack of static typing, such as code complete, and compiler-time checking. When invoking: order.name, the code will compile and we will only discover the failure at run-time. Unit tests can help but might not suffice due to the nature of evolution on services over the web.

As we see, the use of dynamic types greatly facilitates the Restfulie internals. This tendency might also be seen on the Java side as we have JSR-292 wich provides support to dynamic languagues on the JVM. As of April 2003 Robert C. Martin wrote an article called: Are Dynamic Languages Going to Replace Static Languages? and at the end of this article, he make that question: “Will we all be programming in a dynamically typed language in 2010?”. That’s not happened yet, but surely this tendency has gained more strength.

Tags: , ,

Trackbacks/Pingbacks

  1. This Week in #REST – Volume 20 (Jun 14 2010 – Jun 27 2010) « This week in REST - June 28, 2010

    [...] C# implementation of RESTfulie – The power of dynamic – Intro to the C# implementation of RESTfulie. [...]

Leave a Reply