index.js in WebApps

index.js is the entry point and route configuration for a WebApp. The concept is influenced by Express.js. index.js is executed server side, which means SiteVision's Public API can be accessed, while browser objects cannot be accessed.

A simple index.js:

(function() {
   'use strict';

   var router = require('router');

   router.get('/', function(req, res) {
      res.render('/', {});
   });
}());

Routing

Routes handle how a WebApp responds to client requests. All WebApps have a unique segment in the URL where routing information is kept. WebApp routes differ from application routes since WebApp routes are local and should be used to keep state for a single WebApp. The router object provides methods to respond to the following request methods:

  • GET
  • PUT
  • POST
  • DELETE

A route definition has the following structure:

router.method(path, handler);

Basic examples:

var router = require('router'); // retrieve an instance of the router object

// respond to a GET-request to the root route ('/')
router.get('/', function(req, res) { 
   res.send('Hello from my WebApp!');
});

// respond to a GET-request to '/user'
router.get('/user', function(req, res){
   res.send('Hello from user route');
});

Route parameters

Route parameters are used to capture a value in the URL. Below is an example of a path that will capture id on the /user route.

// GET /user/123
router.get('/user/:id', function(req, res) {
 // route is matched and {id: 123} will be populated in the req.params object
});	

Request object (req)

The req object is a representation of the HTTP-request.

Properties

req.params

Object that contains parameters passed to a route. The object contains route parameters ('/user/:id'), query string parameters and values in the request body from POST, PUT and DELETE.

// GET /user/456
router.get('/user/:id', function(req, res) {
   logger.info(req.params.id); // 456
});

// GET /?foo=bar
router.get('/', function(req, res){
   logger.info(req.params.foo); // bar
});

// POST /addToBasket (productId=1)
router.post('/addToBasket', function(req, res){
   logger.info(req.params.productId); // 1
});	

req.cookies

Object that contains cookies from the request.

// Cookie basketId=789
router.get('/', function(req, res){
   logger.info(req.cookies.basketId); // 789
});	

req.xhr

Boolean indicating whether or not the request is an XHR (ajax) request.

router.get('/', function(req, res) {
   if (req.xhr) {
      return res.json({foo: 'bar'});
   }

   return res.render('/', {foo: 'bar'});
});	

req.session

Session data is stored and accessed through the req.session property. Session attributes are namespaced for WebApps/RESTapps, i.e. "global" session attributes cannot be accessed. Note that session data must be JSON serializable.

// WebApp/RESTApp x
router.get('/', function(req, res) {
   req.session.name = 'John Doe';
});
// WebApp/RESTApp y
router.get('/', function(req, res) {
   logger.info(req.session.name); // 'John Doe';
});

req.files

Object containing files (java.io.File) from a multi-part request.

router.post('/', function(req, res) {
   var myFile = req.files.name;
});

req.header(name) [@since 4.5.2]

Request headers from the HTTP-request

router.post('/', function(req, res) {
   logger.info(req.header('host')); //developer.sitevision.se
});

Methods

req.invalidateSession()

Invalidates current session.

Response object (res)

The res object is a representation of the HTTP-response.

Methods

res.set(name, value)

Sets a HTTP-header in the response. Returns this for chaining purposes.

res.set('Cache-Control', 'no-cache')
   .set('X-Content-Type-Options', 'nosniff');

res.type(type) [@since 4.5.2]

Sets the response Content-Type header. If type contains the “/” character, then it will be used as-is. Returns this for chaining purposes.

res.type('.html');      // => 'text/html'
res.type('html');       // => 'text/html'
res.type('text/html');  // => 'text/html'
res.type('svg');        // => 'image/svg+xml'
res.type('txt');        // => 'text/plain'

res.send(response)

Sends a character response. Type will be text/html if not explicitly set.

res.send('<p>Hello from WebApp!</p>');	
res.type('svg')
   .send('<svg version="1.1" ... </svg>');	

res.json(response)

Sends a application/json-response.

res.json({
   id: '123',
   foo: 'bar'
});	

res.sendFile(file)

Sends a file as response. Uses best effort for content type matching if no type is explicitly set. File argument must be a java.io.File or a SiteVision JCR-Node (sv:file or sv:image).

res.sendFile(file);
res.type('application/xml; charset=ISO-8859-1')
   .sendFile(file);

res.status(code)

Sets the HTTP-status for the response. Returns this for chaining purposes.

res.status(404)
   .send('Not found');	

res.render(route, data)

Renders the WebApp. Rendering will always start from the main component. The route parameter will be passed to the data object, which will be the initial state for the WebApp's store.

router.get('/', function(req, res) {
   var data = {
      entries: [],
      buttonText: appData.get('buttonText')
   };
   
   res.render('/', data);
});

router.get('/search', function(req, res) {
   var data = {
      entries: [],
      buttonText: appData.get('buttonText')
   };
   
   res.render('/search', data);
});	

res.redirect(path [, status])

Redirects to a path with a specified status. If a status is missing, it defaults to 302. A "back" redirection redirects the request back to the referer, defaulting to / when the Referer header is missing. A ".." redirection redirects to the relative path above current. Note that redirecting from a regular GET path will not work since the servlet request is commited. Example below shows how to use this method when responding to posted form data.

router.post('/addToBasket', function(req, res) {
   ...
   if (req.xhr) {
      return res.json(json);
   }
   // redirects back to referer
   return res.redirect('back'); 
});

router.post('/addToBasket', function(req, res) {
   // redirects to the URL derived from the /search path
   return res.redirect('/search'); 
});	

res.cookie(object)

Adds a cookie. The cookie is set with httpOnly = false and path = '/'.

res.cookie({
   name: 'basketId',
   value: '123'
});	

res.clearCookie(name [, path])

Clears a cookie given a name. If path is missing, it defaults to '/'.

res.clearCookie('basketId');