UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

169 lines (122 loc) 5.75 kB
REST (Representational State Transfer) ====================================== `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 programmatically. > **note** > > When to use `qx.bom.rest.Resource`? Mostly `qx.io.rest.Resource` delegates to `qx.bom.rest.Resource` and adds some features on top. For **qx.Desktop** apps you probably want to use `qx.io.rest.Resource` but when developing an app/website with **qx.Website** only `qx.bom.rest.Resource` is available (i.e. exposed as website module). > > See the package description for a detailed comparison: [qx.bom.rest](apps://apiviewer/#qx.bom.rest) . 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](http://tools.ietf.org/html/draft-gregorio-uritemplate-07). 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](apps://apiviewer/#qx.io.request.AbstractRequest~requestData) are supported. photo.put({id: 1}, {title: "Monkey"}); // URL encoded photo.put({id: 1}, "title=monkey"); // Raw 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");