# qooxdoo

Home » Manual (v2.0.1) » Communication » REST (Representational State Transfer)

# 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'

## Data

Data that should be included in the request’s body can be given as second parameter. All types accepted by qx.io.request.AbstractRequest#requestData are supported.

    photo.put({id: 1}, {title: "Monkey"}); // URL encoded
    photo.put({id: 1}, "title=monkey"); // Raw
    photo.put({id: 1}, []);

Note that the behavior changes when the request body content type is switched to `application/json`.

    photos.configureRequest(function(req) {
      req.setRequestHeader("Content-Type", "application/json");
    });

    photos.map("post", "POST", "/photos/{id}");
    photos.post({id: 1}, {location: "Karlsruhe"}); // JSON.stringify

## 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");