This project is not currently maintained, but I'd be glad to help fix something if you need it.
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.
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
.
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
.
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');
}
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')}})
}
TBD
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
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');
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
Pull Requests are welcome.
Run the tests with make test
Coverage report is in ./coverage
%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