Structured Data Management for AJAX Applications, Part 1

The AJAX application model lends itself to dynamic, responsive user interfaces.  However, as the application and data model increase in complexity, it becomes harder to keep track of data in a consistent and manageable manner.  This is the first of a series of posts introducing a Javascript library I created called Stache that aims to bring lightweight structured data management to the client side, analogous to the many systems that are common on the server side.

I say analogous, because it’s important to keep in mind that this is not “SQL for the browser”, or a full ORM solution a la Hibernate, or even a means of achieving long term data persistence.  It’s just a simple, relatively transparent way to work with objects that avoids the pitfalls of an ad hoc approach.

The best way to show what it does and how it works is a simple example. Let’s say you have an geospatial AJAX application that needs to work with location fixes on the client side. These have properties such as latitude, longitude, fix time, etc. As you view different parts of the map in this app, the server sends back lists of fixes. To simplify this example, there is no actual server, the data is simply created by instantiating plain old Javascript objects.

So here’s some initial fixes:

var fixes = [
	{
		id:1,
		lat:48.0,
		lon:-74.0,
		fixTime:1340054017000
	},
	{
		id:2,
		lat:50.0,
		lon:-76.0,
		fixTime:1340055017000
	},
	{
		id:3,
		lat:48.0,
		lon:-72.0,
		fixTime:1340056017000
	}
];

Using Stache, this list of fixes would be merged into a common data store, like this:

fixTable.merge(fixes);	

The fixTable is an instance of a data structure used by Stache to track entities on the client side. A follow up post describes how to create these structures. For now, just assume that it exists.

Once POJOs are merged, they become available from anywhere in the app, without the need to make a server request again. Moreover, all references to merged entities point to the same object. Merged entities can be queried, modified, and deleted. They are enriched with mutator and accessor methods, which are used to get and set their field values. Here’s some examples of how to interact with merged entities:

var fix, fixes, lat, lon;
fix = fixTable.get(["ID", 1]);
fix.setLat(49.0);
lon = fix.getLon();
fixes = fixTable.list(["ID", 1, 2]);
fixes = fixTable.list(["RANGE", "lat", 40.0, 50.0]);
fixes = fixTable.list(["AND", 
			["RANGE", "lat", 40.0, 50.0], 
			["RANGE", "lon", -60.0, -80.0]
]);
fixTable.remove(fix);

At some later point, the server might send back more fixes, and those may partially overlap with the existing ones:

fixes = [
	{
		id:3,
		lat:48.0,
		lon:-72.0,
		fixTime:1340056017000
	},
	{
		id:4,
		lat:49.0,
		lon:-72.0,
		fixTime:1340057017000
	},
	{
		id:5,
		lat:50.0,
		lon:-72.0,
		fixTime:1340058017000
	}
];

It’s important to be able to work with the new data and the old data transparently. In particular, fix 3 should not be duplicated, while fix 4 and 5 should be available for querying, modification, etc. Fortunately, the same merge operation used to initialize the fix set earlier can be used to add new data, as well as reconcile duplicates, all in one call:

fixTable.merge(fixes);	

After merging the new data, the same sort of query and modification code above can be used again to work with the full integrated data set. Thus, the usage pattern for Stache is roughly as follows:

  • Obtain data from server
  • Merge data into local tables
  • Query, modify, delete data
  • Repeat as necessary

The example described here was intentionally kept simple, and ignores much of the functionality provided by Stache, including:

  • Data schemas
  • Object, list, and set associations
  • Automatic synchronization of inverse associations
  • Uni-directional and bi-directional self association
  • Property indexing and constraints
  • Deep merging of object graphs

Follow up posts will illustrate these features using more advanced examples, and provide runnable sample code. In the meantime, you can get Stache from GitHub if you want to take it for a spin.

Advertisements

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: