Kondoot Application Template (Kapp)
This repository is designed to make the process of creating node applications that fit into the stack used at Kondoot super simple and repeatable.
Creating a Kapp
Creating a Kapp is very simple, and basic initialization goes as follows:
var app = 'appname';
Options can be specified that influence how a Kapp behaves, and these are covered in more detail later. Once you have completed your application specific initializations you then call app.start()
to get the application to load handlers, configuration information, start the default application server (restify is used by default), etc.
When the application is ready and serving requests it will fire the ready
event, and if the app.start()
call is supplied a callback that will be called shortly after the ready event is triggered.
Baseline package.json for a Kapp
The following represents a baseline package.json
file that should be used to create new a new Kondoot node application (assuming that you want to use restify):
If you are using a different server framework, then remove the dependeny on restify.
A Simple Application (using a Mongo Backend)
var app = 'mongo-example' beforeReady: connectDB ; { appdb = appconfigmongo;} appstart { // if we encounted an error, then report it if err return; // bind handlers // handle mongo configuration changes appconfig;};
NOTE: If the kapp is running in a "seaport enabled" environment then the
Handler Loading
One of the helpful things that Kapp does for you is load route handlers from a handlers
directory from within your application structure. For instance consider the following:
- handlers
|- echo.js
|- hello.js
- server.js
- package.json
In the case above, during initialization Kapp will have autodiscovered the echo and hello handlers for you and wired them into the handlers object (app.handlers.echo
and app.handlers.hello
respectively). It's important to note however that the handlers are not connected to the server instance in any way as defining route handlers and directing them to the handlers is the responsibility of the application.
In terms of the actual handler functions, you are essentially implementing handlers that are identical to the application server you are using in your Kapp application (restify by default), but with a leading app
argument that is injected by Kapp:
// an example echo handlermodule { res;};
This app argument will allow you to access your application object within your handlers without having to try and manage messy external references to the object.
Defining Application Routes
To specify your application routes, the best time to do this is in response to the started
event that is emitted by a Kapp:
app;
Authentication
By default, a KApp expects valid user credentials when serving a request. Valid credentials can either be in the form of:
- a user header (
x-kondoot-user
) and basic auth, or; - through a session details populated by rails (stored in the
_kondoot_session
cookie).
For example, when registering a handler such as the one shown below, if no authentication information is provided, then the KApp will generate a 401
header without you needing to take any specific action:
appserver;
You may notice in the code above that a user's ID can be accessed, through the request object (req.userid
). In the case of unauthenticated requests this will be set to -1.
Specifying Publicly Accessible Routes
To define a route and handler that does not require user authentication, we must define a route as public by using the allowPublic()
method that KApp patches in to restify's native Route
class:
appserver;
Specifying User Accessibly Routes
To define a route that can be accessed directly from the Kondoot frontend (as opposed to through other applications), you need to define the route as allow('user')
. If you accidently type users
that's ok too:
appserver;
Logging in a KApp
KApps use winston for logging by default. While various options for logging were investigated, Winston provides flexible configuration and a wide variety of logging transports. Configuration for logging is set in the distrbuted configuration files.
Access to the logger is provided through the application instance, using the logger
member. For instance, to log a warning the following code could be used:
applogger;
Or more generically using log:
applogger;
During the logging initialization phases, a KApp is configured to use syslog logging levels defined by winston:
- debug (0)
- info (1)
- notice (2)
- warning (3)
- error (4)
- crit (5)
- alert (6)
- emerg (7)
NOTE: Using syslog levels the function is warning
not warn
. That said, the KApp initialization binds a helper from warn
to warning
to stop you getting in to trouble.
The default logging configuration that is used routes log messages of error and above to the console, and messages of warn and able to syslog (which is then passed on to loggly for aggregration). Additional log profiles of info
and debug
are also available to which will put your application into more verbose logging modes. This can be programmatically enabled in an application:
app;
Or through making updates to the centralized configuration section log-overrides
which specify the hostname of the machine you wish to configure to use a logging scheme other than the default scheme.
Advanced: Using a server framework other than RESTify
If restify isn't your favourite framework, then you can easily implement an alternative by providing a createServer
function for the kapp
creation opts. A few examples of implementations for specific frameworks are shown below:
Tako
https://github.com/mikeal/tako
var tako = app; // initialise the appmoduleexports = app = 'tako-example' { var server = ; // tako exposes the listen interface through httpServer and httpsServer // expose the appropriate one through a bound handler serverlisten = serverhttpServerlisten; // return the server instance return server; }; // start the application and create the routesappstart { if err return; appserver;};