qooxdoo

Universal JavaScript Framework

 

REST (Representational State Transfer)

Note

This is an experimental feature.

qx.io.rest.Resource allows to encapsulate the specifics of a REST interface. Rather than requesting URLs with a specific HTTP method manually, a resource representing the remote resource is instantiated and actions are invoked on this resource. A resource with its actions can be configured declaratively or programatically.

Configuring actions

Given a REST-like interface with URLs that comply to the following pattern.

GET      /photo/{id}
PUT      /photo/{id}
DELETE   /photo/{id}

GET      /photos
POST     /photos

Note {id} stands for a placeholder.

This interface comprises of two resources: photo and photos.

To declare the specifics of the REST interface declaratively, pass a description to the constructor.

// Singular resource
var photo = new qx.io.rest.Resource({
  // Retrieve photo
  get: {
   method: "GET",
   url: "/photo/{id}"
  },

  // Update photo
  put: {
    method: "POST",
    url: "/photo/{id}"
  },

  // Delete photo
  del: {
    method: "DELETE",
    url: "/photo/{id}"
  }
});

// Plural resource
var photos = new qx.io.rest.Resource({
  // Retrieve list of photos
  get: {
   method: "GET",
   url: "/photos"
  },

  // Create photo
  post: {
    method: "POST",
    url: "/photos"
  }
});

Or programmatically, for each action.

var photo = new qx.io.rest.Resource();
photo.map("get", "GET", "/photo/{id}");

Invoking actions

Once configured, actions can be invoked. They are invoked by calling a method that is dynamically added to the resource on configuration of the action.

photo.get({id: 1});
// Alternatively: photo.invoke("get", {id: 1});
// --> GET /photo/1

photos.get();
// Alternatively: photos.invoke("get");
// --> GET /photos

When an action is invoked, an appropriate request is configured and send automatically.

Parameters

If the URL contains parameters, the position where the parameters should be inserted can be specified by using URI templates. Parameters are optional unless a check is defined. A default value can be provided.

var photo = new qx.io.rest.Resource();
photo.map("get", "GET", "/photo/{id}/{size=medium}", {id:  qx.io.rest.Resource.REQUIRED});

photo.get({id: 1, size: "large"});
// --> GET /photo/1/large

photo.get({id: 1});
// --> GET /photo/1/medium

photo.get();
// --> Error: Missing parameter 'id'

Events

Events are fired by the resource when the request was successful or any kind of error occurred. There are general resource events and action specific events. Handlers receive a qx.event.type.Rest event that, among other properties, includes the response.

photo.get({id: 1});
photo.put({id: 1});

// "success" is fired when any request associated to resource receives a response
photos.addListener("success", function(e) {
  e.getAction();
  // --> "get" or "put"
});

// "getSuccess" is fired when the request associated to the get action receives a response
photos.addListener("getSuccess", function(e) {
  e.getAction();
  // --> "get"
});

If the same action should be invoked multiple times and the events fired for each request be handled differently, it is possible to remember the id of the action’s invocation. The Rest event includes this id.

var getPhotoId = photo.get({id: 1});
var getLargePhotoId = photo.get({id: 1, size: "large"});
photo.addListener("getSuccess", function(e) {
  if (e.getId() === getLargePhotoId) {
    // Handle large photo
  }
});

Helpers

Helpers make it easy to accomplish common tasks when working with requests.

  • refresh(action) Resend request associated to action. Uses parameters given before.
  • poll(action, params) Periodically invoke action.
  • longPoll(action) Use Ajax long-polling to update whenever new data is available.

Data binding

A qx.data.store.Rest store can be attached to an action. Whenever a response is received, the model property of the store is updated with the marshaled response.

var store = new qx.data.store.Rest(photos, "get");
var list = new qx.ui.form.List();
var controller = new qx.data.controller.List(null, list);
store.bind("model", controller, "model");
photos.longPoll("get");

Table Of Contents

Previous topic

AJAX

Next topic

RPC (Remote Procedure Call)

This Page