node package manager

kona

kona

Node Version Downloads Build Status Coverage Status Dependencies Join the chat at https://gitter.im/jbielick/kona

What is it?

Kona is currently under development, but is published on NPM and on the road to 1.0.

Kona is micro API framework that puts the tools in your hands to get up and running fast. Its mission is to make developing really fast Node.js applications fun and productive, leveraging the generator-based control-flow middleware offered by Koa.

Kona's focus is simplicity; it's a thin layer of the application structure you're used to with room for growing. There aren't a million configurations (yet), you can't swap out the core middleware, you don't need 5 json documents to tell it how to start. The core of framework stack is Koa.js and the middleware stack in Kona is made up of vetted, simple, efficient and modular components. Not sure how Koa works? Kick-Off-Koa may help.

Kona uses ES6 Generator Functions -- part of the ECMAScript 6 draft-standard. This allows your controller (and other) code to perform asynchronous tasks while writing your code as if it were synchronous. A database query function is as simple as var users = yield User.findAll();. Make sure to checkout the Koa workshop or this helpful video if you're new to generators.

Getting Started:

You'll need Yeoman to generate a new kona application. The -g option tells npm to install it globally so you can use the command-line interface and interact with the kona generator. Next, you'll need generator-kona so Yeoman can generate the kona application code. Install this globally as well with the -g option so Yeoman can find it.

You can install them together like this:

> npm install -g yo generator-kona

Now you've got yeoman and the kona application generator. Just generate a new kona application to get started.

> yo kona myNewApp

The kona application generator will build an application in the directory ./myNewApp. It will then run npm install and bower install to install the server and client dependencies you need to run your new application.

Now let's enter the the app directory with cd myNewApp.

You're ready to go!

To start the kona application, just use the npm script or node with the --harmony flag to start the server:

npm start or node --harmony app.js.

example app generation

Environment

The application will start in development environment by default.

To set the application to start in another environment, use an environmental variable like this NODE_ENV=production.

Routing

Kona uses barista for routing.

The features available there are fully-exposed in the config/routes.js file. The routes file exports a function that accepts the application's router as an argument. All barista methods can be called on the router object that is passed into the drawRoutes function.

When mapping a route to a controller and action, use the barista pattern controllerName.actionName. The dispatcher will use this path to resolve the controller and direct the request to the appropriate action.

When mapping a route to a nested (extended) controller, you can use / to indicate the nesting location of the controller the request should be dispatched to.

For example:

If your application had a directory structure like this:

  app/
    controllers/
      geographies-controller.js
      geographies/
        countries-controller.js
  ...

and CountriesController.js extended GeographiesController like this:

// app/controllers/geographies/countries-controller.js 
 
var GeographyController = require('../geographies-controller');
 
var CountriesController = GeographiesController.extend({
  index: function* () {
    var countries = yield this.Countries.find({}).toArray();
    yield this.respondWith(countries);
  }
});

You can route a request to the CountriesController#show method like this:

// config/routes.js 
 
module.exports = function drawRoutes(router) {
  router.get('/countries/:id').to('geographies/countries.show');
}

Mixins

Take advantage of mixins to add functionality and services to your app. By simply installing a kona-* mixin, it will initialize with your app and decorate your controller with the module's functionality.

Take kona-redis for example:

In the root of your kona app, simply install the kona-redis module like you would any other:

npm install -S kona-redis

-S will tell npm to save this dependency to our package.json

! You still need to be running a redis-server for this to work !

And the next time you start your application, your application object and controller context will now have a redis client available at this.redis!

Now you can use redis in your controller action as simply as:

 
  show: function* () {
    this.set('votes', yield this.redis.get('votes'));
  },
 
  vote: function* () {
    yield this.redis.incr('votes');
    yield this.render({json: {votes: yield this.redis.get('votes')}})
  }
 

PubSub (WebSockets)

TBD

Model Exposure

TBD

Would models in the global scope be cool? Sure. But it’s probably not a good idea. Models can have any name—-the global namespace would get horribly messy in big apps, and it would allow / encourage model usage in places it ought not to be.

Models are accessible as singular, PascalCase getters from the controller's this context. You can perform a query or model constructor method right inside the controller action like this:

 
// foo-controller.js 
 
index: function* () {
 
  // mongo.users.find() is a function that returns a promise object 
  var users = yield this.mongo.users.find().toArray();
 
  // respond to the request 
  this.respondTo({
    json: function* () {
      this.render({json: users});
    },
    html: function* () {
      this.set('users', users);
    }
  })
}

this.mongo is an accessor added by the kona-mongo module decoration.

/TBD

Autoloading

In development, Kona’s controller / module loading mimics class autoloading — that is, it doesn’t eager load any modules until they are needed. Once required, they are cached and that cache is invalidated when the file is changed.

In production, all modules are loaded and cached during the application initialization.

You can change the autoloading behavior in dev to work like production by setting config.eagerLoadModules = true;.

You can also add more files to the autoload watch list by pushing relative paths onto the config.autoloadPaths array. ex: config.autoloadPaths.push('app/services');

Directory Structure

The application directory structure in kona is just like Rails'.

Views are stored in the app/views directory and nested by their namespace.

Controllers are stored in app/controllers directory and can also be nested.

app/
  controllers/
    main-controller.js
    user-controller.js
    user/
      admin-controller.js -- AdminController extends UserController
    foo-controller.js
    foo/
      bar-controller.js -- where BarController extends FooController
  views/
    user/
      index.html
      show.html
      add.html
      edit.html
      admin/
        manage.html
    main/
      home.html

Contributing

Pull Requests are welcome. Run the tests with make test Coverage report is in ./coverage

Benchmarks

%benchmarks
siege
  --benchmark
  --log=./benchmark/siege.log
  --quiet
  --concurrent=300
  --time=10s
  http://localhost:3001?foo=bar&baz[qux]=souix
 
 
Lifting the server siege...-      done.
 
Transactions:         7918 hits
Availability:       100.00 %
Elapsed time:         9.91 secs
Data transferred:         0.08 MB
Response time:         0.36 secs
Transaction rate:       798.99 trans/sec
Throughput:         0.01 MB/sec
Concurrency:       289.20
Successful transactions:        7918
Failed transactions:            0
Longest transaction:         0.53
Shortest transaction:         0.03
 
 
%endbenchmarks