Backbone.js Examples

The following examples demonstrate how to use backbone.js to perform CRUD operations on the Stunt·Improvise object database via the REST API.

The specific set of operations allowed, and the information that a player sees and/or can modify, depends on the player’s role and the player’s relationship with the object in question.

A few notes about the current version:

  1. Both the server-side and client-side implementations are limited to operations at the object level. Sub-operations on specific property and/or verb definitions are not supported. Shapes, the database API layer in the Stunt kernel, supports these operations; they just haven’t been exposed through the REST API.
  2. The client-side models perform validations on input data (an object name must be a string, for example) in support of the permission checks and validations performed by the REST API server-side.

These examples are not a replacement for the Backbone.js documentation. If you are not familiar with Backbone.js, I recommend you start there.

The examples below require appropriate versions of underscore.js, backbone.js and moo.js. Your page should include the following:

<script type="text/javascript" src="/js/underscore-1.3.1.min.js"></script>
<script type="text/javascript" src="/js/backbone-0.9.1.min.js"></script>
<script type="text/javascript" src="/js/moo-0.0.1.min.js"></script>

A side-note about security:

The JavaScript same origin policy is in full effect, here. In practice, this means that the AJAX requests that Backbone.js makes to retrieve object data must be to the same origin (protocol, hostname and port) that served up the page. This is not hard to achieve—in fact, the simple home page that ships with Improvise neatly takes care of it.

Assuming you’ve loaded a suitable page, you can interactively fetch and save objects from the server using the Firefox/Firebug or Chrome console. I’m using Chrome for these examples.

Assume an object with the object number #0 lives on the server (one always does). The following code will fetch its representation and instantiate a JavaScript object:

var o = new Moo.Object({id: 0})
o.fetch()

The exact information you get back will depend on whether you authenticated to the server and who you are. An object is made up of collections of verb definitions, property definitions and values (the latter are “properties” in MOO jargon). You can access each via the appropriate collection:

o.verbs.get(0)
o.properties.get(0)
o.values.get('name')

Verb definitions and property definitions are accessed by number (specifically, their id is their position in list returned from evaluation of the expressions verbs(object) or properties(object)). Values are accessed by their name. Both built-in and user-defined values are included.

The examples above return instances of Moo.Verb, Moo.Property or Moo.Value. In the case of values, you typically want the JavaScript value, not the wrapper instance.

o.values.get('name').get('Value.value') // => "System"
o.values.get('programmer').get('Value.value') // => 0
o.values.get('wizard').get('Value.value') // => 0
o.values.get('location').get('Value.value') // => "#2|obj"

JSON only supports string and numeric primitive values. Stunt·Improvise encodes object numbers as strings suffixed with “|obj” and error values as strings suffixed with “|err”.

Assuming you have permission to change the value of a property, you can do so:

o.values.get('name').set('Value.value', "foobar")
o.save()

If you don’t have permission, an error value will be set on object:

o.values.get('name').get('Error.diagnostic') // => "permission denied"

If you try to set an inappropriate value, Backbone.js validations will catch it:

o.values.get('name').set('Value.value', 5)
o.isValid() // => false

The full CRUD lifecycle works as expected:

o = new Moo.Object
o.save()
o.id // => 12345
o.values.get('name').get('Value.value') // => ''
o.values.get('name').set('Value.value', 'foobar')
o.save()
o.id // => 12345
o.destroy()