Introduction To Koa - The Future of Express

Publikováno: 21.5.2018

Express is one of the most popular Node.js frameworks out there. With about about 4+ million weekly downloads, Express has clearly made its mark in the world of...

Celý článek

Express is one of the most popular Node.js frameworks out there. With about about 4+ million weekly downloads, Express has clearly made its mark in the world of Node.js and JavaScript.

Koa is a newly popular web framework created by the team behind Express. It aims to be a modern and more minimalist version of Express. Some of its popular characteristics are its support and reliance on new JavaScript features such as generators and async/await. Koa also does not ship with any middleware though it can easily be extended using custom and existing plugins.

In this article, we will examine the Koa framework and build a simple app to get familiar with its functionality and philosophy.

Requirements

To follow along with this tutorial, you would need the following installed:

You also need to have a working knowledge of JavaScript and ES6 syntax.

Setup and Configuration

Let us get started by setting up our project. First, we will create a new directory for our project. This can be done by copying and running the command below in you terminal:

$ mkdir koala

⚠️ Note: You can give your project any name, but in this article we'll be using koala as our project name and directory.

At this point, we have created our project directory koala. Next, we will initialise our node project from inside the directory. You can do so by running the commands below:

$ cd koala
$ npm init koala 

After running the npm init command, follow the prompts and fill in the details of your project. At the end of this, you will have a package.json file with the information you enetered while prompted.

???? Tip: You can run npm init -y to create a package.json file with default values.

Next, we will run this command to install Koa:

$ npm install koa --save

???? Tip: Depending on the version of Node you have running you may not need to add the --save flag. This flag tells older versions of Node to add the installed library (in this case Koa) to the dependencies list in our package.json file. On newer Node versions, you can simply run npm i koa to install Koa.

Building Out Our App

Creating a Koa Server

During the initialisation of our project, we were prompted to enter the entry point of our application. In this article, we will use index.js which was the default value as our entry point.

First, we will create the index.js file, this can be done in several ways. For MacOS and Linux users, this can be done by running the below command in your terminal:

$ touch index.js

Using your code/text editor of choice, we will open our project and copy the below snippet into the index.js file:

 // index.js

'use strict';

const koa = require('koa')
const app = new koa()

app.use(function *(){
  this.body = "Hello World !!!";
});

app.listen(1234)

In the snippet above, we have created a koa application that runs on port 1234. You can run the application using the command:

$ node index.js

And visiting the application on http://localhost:1234.

Routing In Koa.js

As mentioned earlier, Koa.js does not ship with any contained middleware and unlike its predecessor, Express, it does not handle routing by default.

In order to implement routes in our Koa app, we will install a middleware library for routing in Koa, Koa Router. We'll install it by running:

$ npm install koa-router --save 

To make use of the router in our application, we will amend our index.js file:

// index.js

'use strict';
const koa = require('koa')
const koaRouter = require('koa-router')

const app = new koa()
const router = new koaRouter()

router.get('koala', '/', (ctx) => {
  ctx.body = "Welcome! To the Koala Book of Everything!"
})

app.use(router.routes())
  .use(router.allowedMethods())

app.listen(1234, () => console.log('running on port 1234'))

Above, we have defined a route on the base url of our application (http://localhost:1234) and registered this route to our Koa application.

???? For more information on route definition in Koa.js applications, visit the Koa Router library documentation here.

Templating In Koa.js

As already established, Koa comes as a very minimalistic framework, therefore, to implement view rendering with a template engine we will have to install a middleware library. There are several libraries to choose from but in this article we will use koa-ejs.

To do so, we will first install the library using:

$ npm install koa-ejs --save

Next, we will ammend our index.js file to register our templating with the snippet below:

// index.js

'use strict';
const koa = require('koa')
const path = require('path')
const render = require('koa-ejs')
const koaRouter = require('koa-router')

const app = new koa()
const router = new koaRouter()

render(app, {
  root: path.join(__dirname, 'views'),
  layout: 'layout',
  viewExt: 'html',
  cache: false,
  debug: true
})

router.get('koala', '/', (ctx) => {
  ctx.body = "Welcome! To the Koala Book of Everything!"
})

app.use(router.routes())
  .use(router.allowedMethods())

app.listen(1234, () => console.log('running on port 1234'))

As seen above, in our template registering, we tell our application the root directory of our view files, the extension of the view files and the base view file (which other views extend).

Now that we have registered our template middleware, we will amend our route definition to render a template file:

// index.js

...

router.get('koala', '/', (ctx) => {
  let koala_attributes = [];
  koala_attributes.push({
    meta_name: 'Color',
    meta_value: 'Black and white'
  })
  koala_attributes.push({
    meta_name: 'Native Country',
    meta_value: 'Australia'
  })
  koala_attributes.push({
    meta_name: 'Animal Classification',
    meta_value: 'Mammal'
  })
  koala_attributes.push({
    meta_name: 'Life Span',
    meta_value: '13 - 18 years'
  })
  koala_attributes.push({
    meta_name: 'Are they bears?',
    meta_value: 'no!'
  })
  return ctx.render('index', {
    attributes: koala_attributes
  })
})

...

Above, our base route renders the index.html file found in the views directory. Our index.html file contains some basic HTML to display our koala attributes. See below:

<!-- views/index.html -->

<h2>Koala - a directory Koala of attributes</h2>
<ul class="list-group">
  <% attributes.forEach( function(attribute) { %>
    <li class="list-group-item">
      <%= attribute.meta_name %> - <%= attribute.meta_value %>
    </li>
  <% }); %>
</ul>

???? Tip: For more options with using the koa-ejs template middleware, view the library documentation here.

Handling Errors and Responses

Error Handling

Koa handles errors by defining an error middleware early in our entrypoint file. The error middleware must be defined early because only errors from middleware defined after the error middleware will be caught. Using our index.js file as an example, we'll adjust it to include:

// index.js

'use strict';
const koa = require('koa')
const render = require('koa-ejs')
const koaRouter = require('koa-router')

const app = new koa()
const router = new koaRouter()

app.use( async (ctx, next) => {
  try {
    await next()
  } catch(err) {
    console.log(err.status)
    ctx.status = err.status || 500;
    ctx.body = err.message;
  }
})

...

The above block catches any error thrown during the execution of our application. We'll test this by throwing an error in the function body of the route we defined:

// index.js

...

router.get('koala', '/', (ctx) => {
  ctx.throw('Test Error Message', 500)
}) 
...

Handling Responses

The Koa response object is usually embedded in its context object. Using our route definition, we will show an example of setting responses:

// index.js

'use strict';
const koa = require('koa')
const koaRouter = require('koa-router')

const app = new koa()
const router = new koaRouter()

app.use( async (ctx, next) => {
  try {
    await next()
  } catch(err) {
    console.log(err.status)
    ctx.status = err.status || 500;
    ctx.body = err.message;
  }
})

router.get('koala', '/', (ctx) => {
  ctx.status = 200
  ctx.body   = "Well this is the response body"
})

Conclusion

In this article, we had a brief introduction to Koa and how to implement some common functionalities in a Koa project. Koa is a minimalist and designed-to-be-flexible framework that can be extended to more functionality than this article has shown. Because of its futuristic approach and similarity to Express, some have even described it as Express 5.0 in spirit.

The entire code from this article is available on Github, and the repository contains some additional concepts not treated here, as they are beyond the scope of the intro. We'd love to hear about what you've done with Koa.js. Please share in the comments below!

Nahoru
Tento web používá k poskytování služeb a analýze návštěvnosti soubory cookie. Používáním tohoto webu s tímto souhlasíte. Další informace