Restlet JS

Design

This document provides the new design of Restlet JS. Its more JavaScript friendly and easily to configure and use by keeping core concepts of the framework.

It supports both server and client sides. The client side only provides a REST client to consume RESTful services.

In this document, we will describe the API of the framework to both implement and consume RESTful applications.

Components and servers

Component

Here is the way to create a component:

var component = restlet.createComponent(); 
var component = restlet.createComponent(
{
    name: "my component",
    description: "description",
    (...)
});

(...)

component.start();

(...)

component.stop();

Configuring server

Here is the way to define and configure a server for a component:

component.addServer("http", 3000); 
component.addServer("https", {
    port: 3001,
    timeout: 3000,
    (...)
});

Restlet element

Restlet element creation

Create a restlet element from a function:

var element = restlet.createRestlet(function(req, res) {
   (...)
});

Automatical wrapping into an object when creating a restlet element from functions.

Chaining Restlet elements

Configure training between restlet elements:

var element = restlet.createRestlet(function(req, res, next) {
    (...)
    next();
}).next(otherElement);

Another way only using functions:

var element = restlet.createRestlet(function(req, res, next) {
    (...)
    next();
}).next(function(req, rest) {
   (...)
});

Filters

Create filter and define its next element:

var filter = restlet.createFilter(function(req, res, next, stop)  {
    // filter content
    next();
    // or
    stop(); // explicitely set an error on response and call end
});
filter.next(router);

Routing

Routers

Create a router and attach an handling function:

var router = restlet.createRouter();

router.attach('/path', function(req, res) {
    (...)
});

Create a router and attach filter:

var router = restlet.createRouter();

var filter = restlet.createFilter(function(req, res, next, stop)  {
    (...)
});
filter.next(router);

router.attach('/path', function(req, res) {
    (...)
});

Attach a Restlet

Attach handling function on router:

router.attach('/path', function(req, res) {
});

Define path variables when attaching handling function:

router.attach('/path/{var}', function(req, res) {
    var varValue = req.pathVariables.var;
    var myParamValue = req.queryParameters.myParam;
});

Set the matching mode

Define matching mode:

router.attach('/path', {
    matchingMode: 'equals' | 'startsWith',
    query: true,
    match: function(req, res) {
        (...)
    },
    handle: function(req, res) {
    }
});

Application

Create application and attach it to component host:

var application = restlet.createApplication(function() {
    // inbound
});
component.getDefaultHost().attach('/path', application);
component.getDefaultHost().attachDefault(application);

Next function detects if its a function or an object. In the case of a function, the latter is wrapper into an object (method handle).

Inbound and outbound

Specify both inbound and outbound of an application:

var application = restlet.createApplication(function() {
    // inbound
}, function() {
    // outbound
});

Server resource

Creation

Default creation of a server resource:

var resource = restlet.createServerResource();

Creation of a server resource and provide a general handling function:

var resource = restlet.createServerResource(function(request, response) {
    // Handle
    (...)
});

Creation of a server resource and provide a general handling function with parameters:

var resource = restlet.createServerResource({
    method: 'GET',
    (...)
}, function(request, response) {
    // Handle
    (...)
});

Configure request handler

Configure an handling function with parameters:

resource.configure({
    method: 'GET',
    accept: 'json',
    convertInputRepresentation: true | false,
    convertOutputRepresentation: true | false, // ?
    parameters: ['request','response','entity','clientInfo','pathVariables["varName"]','queryParameters["paramName"]', 'reference'],
    match: function(req, res) {
        // Check if the handler matches
    }
}, function(req, res) {
    (...)
});

The name of the method (configure) isnt perhaps the best one.

Internally add the request handler within the array handlers.

Request handler configuration object

Define several methods using call chaining

Add handling functions for HTTP methods using function chaining:

resource.get(function(req, res) {
    (...)
})
.post(function(req, res) {
    (...)
});

Configuration shortcuts

Specify HTTP method:

resource.get(function(req, res) {
});

is equivalent to:

resource.configure({
    method: 'GET'
}, function(req, res) {
    (...)
});

Specify HTTP method and expected media type:

resource.getJson(function(req, res) {
});

is equivalent to:

resource.configure({
    method: 'GET',
    accept: 'json'
}, function(req, res) {
    (...)
});

Specify HTTP method and expected media type:

resource.putJson(function(req, res) {
});

is equivalent to:

resource.configure({
    method: 'PUT',
    accept: 'json'
}, function(req, res) {
    (...)
});

Specify HTTP method, expected media type and to convert received payload to object using converter:

Specify payload conversion

resource.get({
    accept: 'json',
    parameters: ['request','response'] | parameters: ['entity']
    convertInputRepresentation: true | false
}, function(req, res) {
    res.writeObject({ name: 'name' });
})
.post(function(req, res) {
    res.writeText('test');
    res.end();
})
.put({
    accept: 'json',
    parameters: ['request','response'] | parameters: ['entity']
    convertInputRepresentation: true
}, function(obj) {
    res.writeObject({ name: 'name' });
});

Entity streams

  • Extract text from request when calling method getText.
  • Provide methods to have accessible to input entity stream.
  • Provide methods to have accessible to ouput entity stream through the response object.

Request object

req.queryparams.myParamName
req.pathvars.myVarName
req.headers.myHeaderName
req.getClientInfo()
req.getReference()
req.getText()
req.getEntityStream() | req.getInputStream()

Response object

res.writeObject(obj) //??
res.writeEntity({
    mediaType: 'application/json',
    modificationDate: '',
    tag: '',
    variant: '', 
    content | text:
});
res.write(text | xml | json | obj); // detect the right converter to use
    // for text: wrap it automatically within a representation obj
    // for xml: choose the XML converter
    // for json | obj: choose the right converter according to the expected content (header accept)
res.write(text | obj, mediaType)
res.getEntityStream() | res.getInputStream()
res.mediaType(mediaType)
res.end();
res.status(200); // Use default text
res.status(200, text);
res.status(200, obj);
res.error(code, text | obj);

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s