Co.Koa

An MVC for NodeJS built on Koa

View on GitHub
Home | Documentation | Core | CLI | Install

Co.Koa header

A Note on Conventions

Co.Koa is a Convention Over Configuration framework. It endeavours to keep configuration to a minimum so you can focus on writing well-ordered human-readable code. If you haven’t worked with a Convention over Configuration toolchain before, it can be a little intimidating at first. Rest assured, once you know the lingo, it’s a piece of cake!

Overall, it is advised to play by the following rules:


The models folder must only contain models, most other locations are fair game!

Because of how the Dependency Manager works, you will run in to problems if you put Plain Old JavaScript files in the models folder.

The same is not true with Controllers, Services, Validators or custom folders of your choosing within the API directory. For Co.Koa to recognise a Service or Controller its file name must be suffixed with their respective Type (Controller/Service/Validator).

Keep in mind when adding unconventional JS to your software that Co.Koa will not know what to do with it. At some stage there may be scope for making Co.Koa smart to custom dynamic types; but, at present, what you see within this Documentation is what you get.


Co.Koa has rules, but play by them and the rest is really all yours

NPM modules and your own unconventional code is only ever a require call away! if you want to use custom libraries within the different conventional js components of the build, simply require them as usual:

const _ = require('lodash');

module.exports = function TestController ($) {
  return {
    async 'GET /compact' (ctx, next) {
      const compacted = _.compact([0, 1, false, 2, '', 3]);
      ctx.body = compacted;
    }
  }
}

Try to keep the nomenclature consistent

Nomenclature is not enforced with an iron fist, but if we work to the same conventions across builds, our code becomes much easier to share and understand. Please try to use the conventions below wherever using the Dependency Manager:

Model files should have their first letter capitalised; when declared, they should be assigned to a capitalised variable of the same name:

const Book = $('Book');

Services and Validator files should have the first letter of their names capitalised. However, because they are considered to be instances rather than modelled objects, they should be assigned to “camelCased” variables as below:

const bookService = $('BookService');
const bookValidator = $('BookValidator');

when assigning Static Resources to a variable, it is encouraged to prefix the variable name with an underscore:

const _enums = $(':enums');
const _echo =  $(':echo');

Be Wary of Calling the Dependency Manager repeatedly when a variable assignment will do

Much like JQuery, it is a good idea to assign your Dependency Manager calls to variable at the top of your module export rather than having them occur repeatedly. Calls to the Dependency Manager (particularly calls to models) are computationally expensive. Try to avoid writing code like the below:

$(':async').each(
  ['Foo','Bar'], // the array to iterate over
  async (name) => { // use the async library's each method to iterate over array
    await new $('Sample')({ name: `My name is: ${name}` }).save();
});

The above would be better expressed as:

const _async = $(':async');
const Sample = $('Sample');
...
await _async.each(
  ['Foo','Bar'], // the array to iterate over
  async (name) => { // use the async library's each method to iterate over array
  await new Sample({ name: `My name is: ${name}` }).save();
});

Only put non-sensitive data in the Public folder

If it’s in the Public folder it’s available to the world at large. Co.Koa uses koa-static under the hood, feel free to serve your own custom static assets.


If all else fails, defer to app.js

app.js exposes the Koa modules’ app object via coKoa.app. If you’re struggling to implement middleware via ./config/middleware.js, you can inject your own implementations within app.js itself. Bear in mind that any middleware implemented in this fashion will be triggered after the middleware within ./config/middleware.js.