ExoWeb’s Entity System

In this post I present a short overview of the key concepts that describe how ExoWeb establishes JavaScript “classes” on the client to represent entities in your object model. Because its brand new, the first question however is: what is ExoWeb?  Bryan Matthews in his overview of ExoWeb (read it!) has a nice description: “ExoWeb exists to bridge the gap between the client and server.”  In other words its a JavaScript library that moves your app’s object model to the web browser to make AJAX-style apps easier.

Luckily the classes ExoWeb generates for your entities will likely seem quite familar to you. ExoWeb lets you write JavaScript like this (contrived example):

// prompt for the person's new name
myPerson.set_Name(window.prompt("Edit Name", p.get_Name()));
// insert a new dog as a pet
myPerson.set_Pet(new Dog({Name: "Fido", Weight: "20"}));
// save the changes on the server
window.context.server.save(myPerson);

We’ve done our best to make sure the parts and pieces that comprise the ExoWeb entity system work consistently, fit together cleanly and take advantage of JavaScript’s language features. Here is a short overview of the essential concepts as to how ExoWeb entity classes and objects work (after they have been loaded on the client — more on that another day):

Classes

Client-class per server-class – There’s one JavaScript class generated by ExoWeb for each class in your server-side object model. Classes can be selectively loaded for efficency so only the classes you need are sent to the client.

JavaScript friendly – Each entity class comes with all of the standard benefits of javascript classes so new, instanceof, prototypes and inheritance all work as expected:  new Person() instanceof Person == true.

Inheritance – Classes support single inheritance implemented via JavaScript prototyping. All generated entity classes ultimately derive from ExoWeb.Model.Entity.

Object Identity, Construction and Pooling

Object ids – Every instance, including yet to be persisted ones, have a single string identifier associated with it.  If server-side objects have non-string ids (such as numbers, guides, or multipart ids) they will be converted to a string representation for use in the client object model.

Every instance has a unique id – No two instances can share the same ID. Period.

Equals (==) works – new Person(1) == new Person(1).

New objects have ids too, and they may change – A client-only id is assigned to new, yet to be persisted, objects. If the object is later persisted and an ID is assigned server-side, ExoWeb will reflect the new id on the client but keep the temporary one around behind the scenes so that they are both valid references.

Objects are created via their constructor – This works as you’d expect. If the object already exists server-side, pass its ID into the constructor: new Person(); or, new Person(1).  There are also some shortcut constructors to combine construction and property (see the pet example at the beginning of this post).

Objects are pooled – ExoWeb tracks objects in an object pool.  Object construction queries and updates the pool as needed.  Invoking the same constructor with the same ID twice will result in a single object being created (new Person(1) === new Person(1))

Pooling works with inheritance – Subclass instances appear in their base class’ pools. new Dog(32) === Animal.meta.get(32)

Object Properties and Methods

Objects have properties – The properties are generated based on the server-side object model.

Objects have methods – Methods are generated based on the server-side object model and cause a server roundtrip to occur when invokved.  Client-only methods can also be defined.

Property getters/setters – Properties are accessed via getters and setters:  myObj.set_FirstName(“George”); myObj.get_FirstName().  This may seem annoying, and should be familar to Java developers, but is required so that eventing, validation and rules will work.

Properties are typed – Each property is of a specific type and both either entity types or javascript intrinsic types are supported. If a property’s value is set to the wrong type and exception is thrown and the value is discarded.

Property change eventing – Events are raised when properties change which can trigger UI updates.  Changes are tracked behind the scenes by ExoWeb so they can be persisted later.

Property validation – Properties are validated based on metadata provided by your ORM. Validation events can be used to drive validation presentation in the UI.  Checkout the jQuery plugin we’ve put together that makes this easy.

Client-only properties – Properties can be declared in JavaScript on the client to help simplify certain UI tasks.  Checkout the $extend() function for more details.

Calculated properties – Properties can have calculated values.  ExoWeb automatically recalculates the property when one of its dependencies change. Like other all properties, a change events are raised so the UI can reflect the changes.

Metadata

Class metadata – Information about each entity type, such as properties, are available client-side through the type’s meta property:  Person.meta

Object metadata – Each object has metadata, such as its identity and type metadata, accessible via its meta object:  myObj.meta

Conditions metadata – Information calculated about the current state of each object are tracked as object conditions.  This includes things like validation errors and basic security checks. This concept was taken directly from ExoRule, our open source rules engine.

Advertisements

About this entry