Marley

Marley is a framework for quickly building RESTful web services and applications. It consists of several parts:

  • A simple Rack application that acts as request parser/router.

  • A default controller for ORM model classes.

  • Two plugins for the Sequel ORM.

    • RestConvenience - Connects the class to a default controller.

    • RestAuthorization - Adds default authorization methods to a model class and its instances.

  • Marley Joints - A framework for creating reusable Marley resource sets.

  • Reggae - A JSON data format

  • Jamaica - A minimal JS/jQuery client which renders Reggae resources as browser DOM objects.

The point of the whole thing is to minimize the amount of non-model (non-datacentric) code that needs to be written to implement a web service/application.

Please see the examples/forum.rb and the included Joints’ code to get a basic idea of what a Marley application looks like.


Marley Resources

Marley resources are constants in the Marley::Resources namespace.

  • A resource must respond either to a #controller method or to one or more REST verbs (#rest_get, #rest_post, #rest_put, or #rest_delete).

  • A #controller method must return an object that responds to one or more REST verbs.

  • REST verb methods should return an object with a #to_json method.

The Parser/Router

The parser splits the request path on ‘/’ and treats the first part as the requested resource. If no resource is specified in the request, it uses the default resource.

if the resource has a REST method corresponding the the request verb, the parser calls that method and sends the return value to the client.

The parser also traps various errors and returns the appropriate error message to the client.

The Sequel plugins

Marley activates both of them for Sequel::Model. This will soon change to an option.

The Default Model Controller

One of the things that the RestConvenience Sequel plugin does is add a #controller method to affected models. This method instantiates and returns a ModelController object for the model in question. At initialization, the Controller parses the request path to determine the model instances to which the request refers.

Joints

“Joints” are pre-packaged resource sets that can be included in a Marley application. A joint can be added to the current Resources by running Marley.joint(‘joint_name’). The Marley.joint method will then do the following:

  • Find a file named ‘joint_name’ in the ‘joints/’ directory.

  • Require that file.

  • run its #smoke method.

The Joint#smoke method looks for 3 modules inside the joint’s namespace: Resources, ClassMethods, and InstanceMethods.

  • if the Resources module exists, Joint#smoke will copy all of its constants to Marley::Resources.

  • If the ClassMethods module exists, Joint#smoke will cycle through the modules within it, and extend objects in Marley::Resources with the same name.

  • If the InstanceMethods module exists, Joint#smoke will cycle through the modules within it, and call their #append_features with the corresponding objects in Marley::Resources with the same name.

For now, there are 5 joints included in the Marley distribution:

  • Basic User

  • Basic Messaging

  • Basic Menu System

  • Tagging

  • Tagged Messaging

With a bit of configuration, these comprise the example forum application, which is in turn the targt for the test suite.

Reggae

The server and client use a JSON based data representation format “Reggae.” Reggae.ebnf describes the format in canonical form, and reggae.rb contains a Reggae parser and generator.

Jamaica

The default Marley client is “Jamaica”, which consists of JS/CSS for browsers. It sucks right now and I’m hoping somebody takes it over as a sub-project, but it does work - at least on FF.