A Simple Example of Network-Oriented Architecture

Published By: Jason Kolb on January 18, 2007 - 10:44am
Original Blog Entry Located Here
Filed In: Networking

The last post I wrote about Network Oriented Architecture (a term I made up) seemed to generate some confusion. While a picture is worth a thousand words, when you’re talking about programming, a line of code is usually worth about the same. So I figured it would be a good idea to show a simple example, I think it might better illustrate what I’m talking about.

If you read my previous post on this topic you’ll see that what I really want to achieve here is a programming environment that seamlessly extends from the server to the client. To briefly recap the last post, that would result in:

  • A security model that allows the server to definitively identify the client, and ideally identify clients running on OTHER servers as well. There is no easy way to authenticate and authorize Web clients right now, and no technological reason why it can’t be done. This is going to be key once always-on personal nodes such as iPhones start to become widely adopted, and very closely tied to online identity.
  • The ability to use server resources such as objects on the client. For example, I should be able to create an object on the client that exists on the server and call its methods in the browser.
  • The ability to maintain synchronized state between objects living on the server and the client. If I update and save something on the client, the server should be updated automatically. I shouldn’t have to manually make a call to anything. Conversely, if another client or something on the server updates and saves a resource all clients that are using that resource should be automatically notified and updated as well.
  • A way for resources on the client to use resources on other servers. I can’t see any reason why clients shouldn’t be able to use resources that live on more than one server. It is, after all, the World Wide WEB.
  • A way for server-side resources to represent themselves visually on the client. If server-side resources can extend to the client, there’s no good reason why the server objects shouldn’t be able to take care of displaying themselves on the client as well. It’s one less thing to do in code, and something that I don’t even recall being done in the OLD client-server environment.

For the sake of example, let’s run through a very simple use case. Let’s say that I want to update a customer's information as a result of some action the user took in the browser. On the server we have a database with just two tables: a customer table, and an address table as well (remember, this is way simplified). Sitting on top of the database is an object model. Customers have addresses, and that's the extent of the object model:

Noa_object_model_1

For the server-side architecture I used a highly customized version of the NetTiers templates because they provide an architecture model that I really like along with a lot of customizability. (By the way, if anyone is aware of a set of templates like NetTiers for Java I would LOVE a link!)

One of the things I did differently than normal with this object model was to use URI's as primary keys for everything. Because of that I was able to write a custom HTTP handler on the server that acts as the public endpoint for every object in the database:

Noa_http_handler

Although it's technically part of the server, I view the custom HTTP handler as more of a neutral translator between the two tiers. What it really does is inspect incoming requests and see if they're for A) a static resource such as a page or an image, in which case it does nothing, or B) an object. In the case of an object, the handler circumvents the normal page processing engine and uses URL rewriting to find out which object is being requested. So while http://www.jasonkolb.com/customer/customerabc and http://www.jasonkolb.com/addresses/homeaddress are two different URI's with two different paths, they both end up at the same HTTP handler which can translate them into the appropriate objects on the server. Since the URI that was requested is also the object's primary key, it's almost trivial to load the object based on the URI that was requested.

So back to the example. NetTiers provides SOAP services for free, but that doesn't help me a whole lot in client-side Javascript. However, it would be pretty easy for me to write a template for a REST service that I could call from Javascript. I won't bore you with the code here since it's a little long, but if you're interested you can find out all the details on writing REST services in ASP.NET here.

On the client, I’d first use an asynchronous XmlHttpRequest call to send the request for the object, having it sent to a callback function where the update could take place. (Please be kind, this is more along the lines of pseudo-code than actual production code):

var http = getHTTPObject(); // Get an XmlHttpRequest objecthttp.open("GET", "http://www.jasonkolb.com/customer/customerabc", true);http.onreadystatechange = function() {	if (http.readyState == 4) {		// Received the object in JSON encoding		var theCustomer = eval('(' + http.responseText + ')');		// Update the customer		theCustomer.FirstName = "Bubba";		// Send the change to the server		var http2 = getHTTPObject();		http.open("PUT", "http://www.jasonkolb.com/customer/customerabc", true);		http2.send(theCustomer);	}}// Send the object request to the serverhttp.send(null);

So there we go, our customer record is now updated. However, that is NOT a seamless extension of the server-side object model on the client. It’s more along the lines of a Javascript application talking to a C# application over the wire. When the user interface needs to talk to a third-party Web service it gets even worse, because then you have a Javascript application talking to a server application which is talking to another application and then relaying the result back over the same daisy-chain, ala the telephone game.

Instead, let's try this NOA-style. If we can extend the server-side object model to the client, we should be able to do this (and we can):

// Get the objectvar theCustomer = GetObject("http://www.jasonkolb.com/customer/customerabc");// Change ittheCustomer.FirstName = "Bubba";// Save the changestheCustomer.Save();

All of the XmlHttpRequest plumbing and service-oriented-everything is abstracted away behind the scenes. And what's more, the methods can be automatically generated for the server-side object methods, and dependencies can be injected. So if the Customer class has HomeAddress property that is an Address class, and a RequestFreeSample() method that accepts an Address object, all of that can be handled without any extra effort as well. It looks like this:

var theCustomer = GetObject("http://www.jasonkolb.com/customer/customerabc");theCustomer.RequestFreeSample( theCustomer.HomeAddress );

Let me point out that I built this system on top of Dojo, primarly because it has a great packaging system which I was able to use to shuttle server-side classes to the client with minimal work. It allowed me to write and inject object dependencies so that depending on which classes are used, the code automatically detects any classes needed and loads them into memory automatically. I know in advance that any classes needed by the Customer class, such as the Address class, are loaded and usable by the time I need them. The Dojo engine will automatically go find the required Javascript files and parse them into the application.

The Javascript object methods for the classes are generated by reflecting the server-side object methods, and are simply proxies that send the arguments and the object state to the server, and return the result--they are shells that don't actually contain any logic of their own. While there's still a lot of activity going on behind the scenes it's all very seamless from a programming perspective.

The beauty of this approach, and the reason that I called it Network-Oriented Architecture, is that these object URI's can be called by other Javascript applications as well, even ones that are being served from other domains. It essentially gets rid of any dependency between the client and the server. And it’s entirely possible to use a resource that lives on a completely different server other than the one serving the Javascript application if that’s what you want to do. This code, which uses objects living on two different servers, would work just as well:

var theCustomer = GetObject("http://www.jasonkolb.com/customer/customerabc");var theAddress = GetObject("http://www.somebodyelse.com/address/homeaddress");theCustomer.RequestFreeSample( theAddress );

The objects returned from any other remote server still have the same capabilities--you can still call their methods, change their properties, etc. I think that’s pretty cool.

I was going to continue on and write about how these objects can be connected to HTML DOM objects on the front-end so that they're capable of rendering themselves, but this post is getting a little long and it's getting late. Instead, I'll keep this post a little shorter and save the rest for next time, but if you're interested in reading more about it now I did actually talk about that component in a roundabout way in my post called "Portrait of an Object".

In the meantime, I hope this clarifies things a little. I'd love to hear some feedback on what people think about this type of programming, and if I'm just all wet or if this actually makes sense to other people.


Sponsored White Paper
Recent Blog Entries