syntaxhighlighter

Monday, September 3, 2012

Code documentation - express-examples/sqlite

State of the art

Code documentation appears to be not so clear into JS world. I've been reading several pages and blogs about this, and finally I got 2 main solutions, jsdoc-toolkit and ScriptDoc.

At the beginning I leaned for ScriptDoc, because people say is very similar to Javadoc and some days ago I developed a mobile app using Titanium. But, I found JSDoc more mature, even when the project appears to be forgotten (last commit on June 2010).

Finally, I selected JSDoc. Here is a list of people using it. The project documentation here and a list of tags here.

An example

From /lib/rest/common.js

/** 
* @fileOverview Common JS for REST services (express-examples/sqlite)
*
* @author Rodolfo Campos <camposer at gmail dot com>
* @version 1.0
*/

/**
 * HTTP codes 
 * @see For all HTTP codes refer to: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 
 */
var HTTP_CODE_OK = 200
  , HTTP_CODE_UNAUTHORIZED = 401
  , HTTP_CODE_FORBIDDEN = 403
  , HTTP_CODE_NOT_FOUND = 404
  , HTTP_CODE_METHOD_NOT_ALLOWED = 405
  , HTTP_CODE_PRECONDITION_FAILED = 412;

/** 
 * JSON Content-Type HTTP Header
 * @field
 */
var JSON_RESPONSE_HEADER = {'Content-Type': 'application/json; charset=utf-8'};

/** 
 * Writes HTTP code 200 and Content-Type for JSON in HTTP response headers
 * @function 
 * @param {HttpResponse} res HTTP response 
 * @param {Number} code HTTP code to be written in header
 */
var ok = function(res) {
  res.writeHead(HTTP_CODE_OK, this.JSON_RESPONSE_HEADER);
};

/** 
 * Writes HTTP code 4XX (error) and Content-Type for JSON in HTTP response headers
 * @function 
 * @param {HttpResponse} res HTTP response 
 * @param {Number} code HTTP code to be written into header
 */
var nok = function(res, code) {
  res.writeHead(code, JSON_RESPONSE_HEADER);
};

/**
 * Executes validate method using params, if true, calls execute method, if not, returns HTTP code 412
 * @param {HttpResponse} res HttpResponse object
 * @param {Mixed|Object} params Can be value or object (JSON)
 * @param {Function([params])} validate Function used for validation, if returns true everything is OK, 
 *   if not something went wrong and call returns HTTP_CODE_PRECONDITION_FAILED(412)
 * @param {Function(params, callback)|Function(callback)} execute Function executed if validate=true. 
 *   Parameters (params) can be value (e.g. String) or Object (JSON). Callback should receive 
 *   one parameter (result) 
 *   
 * @example 
 * common.call(
 *   res, 
 *   params.name, 
 *   function(name) { 
 *     var valid = true;
 *
 *     if (name == null) 
 *       valid = false; 
 * 
 *     return valid;
 *   },
 *   function(params, callback) {
 *     // ...
 *     // Get result
 *     callback(result);
 *   }
 * );
 */
this.call = function(res, params, validate, execute) {
  if (validate(params)) {
    if (params != null) {
      execute(params, function(result) { // TODO: Add extra parameter for error msg
        if (result) 
          ok(res); 
        else 
          nok(res, HTTP_CODE_FORBIDDEN); 

        res.end(JSON.stringify(result)); 
      });
    } else {
      execute(function(result) { // TODO: Add extra parameter for error msg
        if (result) 
          ok(res); 
        else 
          nok(res, HTTP_CODE_FORBIDDEN); 

        res.end(JSON.stringify(result)); 
      });
    }
  } else {
    nok(res, HTTP_CODE_PRECONDITION_FAILED); 
    res.end(); 
  }
};

Generating documentation

For generating the HTML documentation corresponding to the example above (common.js), you just have to download jsdoc-tool from here, unzip it, and run the following command:

$ java -jar jsrun.jar app/run.js -a -t=templates/jsdoc -d=common common.js

Where:

  • jsrun.jar: Generator
  • app/run.js: Bootstrap script
  • -a: Include all functions, even undocumented ones
  • templates/jsdoc: Directory of the templates to be used
  • -d: Directory where output is going to be put. By default ./out folder
  • common.js: File parsed

For JsDoc inline documentation use:

$ java -jar jsrun.jar app/run.js --help

You can use -r option for generating documentation recursively, specifying a directory to be explored. I like this option, but specifying directories, for example:

$ java -jar jsrun.jar app/run.js -a -t=templates/jsdoc -d=sqlite -r ~/express-examples/sqlite/lib/rest ~/express-examples/sqlite/lib/service

Note: If you specify the root directory as starting point, you're going to have a mess with all JS files in the project (including node_modules).

Updated code documentation can be found inside the project at /jsdoc folder.