What Is Koa.js?
Hi, this is James at no.com. In this screencast, I'm going to show you how to create a web application in node.js using the new web framework, Koa JS.
If you're like me, you may be thinking, "Great, another node.js web framework I have to consider." I've had this same sentiment countless times. However, what you need to know is that Koa JS isn't like any other node.js web framework that I'm aware of. It's the first web framework built from the ground up using generators, a new feature in JavaScript that significantly simplifies asynchronous programming.
If you're not familiar with JavaScript generators, you should check out my screencast on the topic, which I've linked to on this page. Okay, let's build an app in Koa Js.
Environment Setup
First off, I need to install Koa, which at this point in time requires a special version of node.js. As I mentioned a moment ago, Koa JS relies on JavaScript generators, which are still a pretty new feature in node.js and are currently only supported on the 0.11 branch.
So you can either download the appropriate version by going to nodejs.org, clicking 'download other releases', and downloading the appropriate version such as 0.11.14, or what I would suggest is using N, the Node Version Manager, which allows you to easily switch between different versions of Node.
To do this, you first install the latest version of node from nodejs.org. Now, install N. You can install N by typing npm install with the global parameter and then n. After the N node version manager is installed, you can change your current version to 0.11.14, which is the latest as of this recording, by typing sudo n 0.11.14.
Now I'm going to install Koa in a new app directory with the command npm install koa.
Your First Koa App
Okay, everything's set up. Now let's go ahead and create a very minimal Koa JS app. First, I'm going to require the Koa module that we just installed. Now I'm going to instantiate a Koa object which creates our app. Okay, so we have our app. Now the question is, how do we interact with it?
I think it's helpful when you're starting out to simply think of Koa JS as an application with an array of functions that it executes when requests are made. You as the developer will simply add functions to the array that Koa JS maintains to handle the requests. These functions, to be more specific, generator functions, are called middleware, which we will look at more in a few moments.
The way that I add my functions to Koa.js is by passing the function into the use method provided by the KJS app. When KJS is handling requests, it will look at the function or functions that you have added to it in the exact order that you've added those functions. This should make more sense as I show you a concrete example.
For now, we'll keep it simple and add just one generator function. If you aren't familiar with generators, the syntactical difference between a regular function and a generator function is the asterisk that is placed after the function keyword. Okay, so now we're in the generator function and the question is, how do we know what the request is and then how do we respond to that request? In most other web frameworks, the request and the response objects are passed into the function. However, in Koa JS, these objects are attached to the this keyword.
So to respond to a request, we can use the response object by setting this.response.body to something such as a string, or a buffer, or an object, or a stream. Now, because the body property is used so frequently, Koa.js has an alias of this.body, which really points to this.response.body. So we can save ourselves some keystrokes by eliminating the response and just use this.body. In this example, I'm just going to respond with a 'Hello from Koa JS'.
Running and Testing the Server
One other thing I need to do is tell the Koa JS app what port number to listen to. I'll use port 3000. Okay, I'm going to start the server using node.js. Now at this point in time, to use generators in node, I need to pass the --harmony flag to the node command. And lastly, I'll enter the server name and press enter.
Now let's test my simple web server by opening Chrome and navigating to the Local Host on port 3000. Okay, I received a response that I was expecting, 'Hello from Koa JS'.
Implementing Basic Routing Logic
Let's add some conditional logic to our server. Let's say if the requested URL to the server is /date, we'll return the current date. Otherwise, we'll just respond with 'Hello from CJs'.
Okay, I mentioned earlier I have access to the request information via the request object. I want to inspect the request object so I can figure out how the URL is made available to me. So I'm going to go ahead and log the this.request to the console to see what's contained in the request object. Now since I've changed my code, I'll need to restart the node server. This is done by pressing control C, then I'll hit the up arrow on my keyboard and then I'll press enter to start the node server again.
Now let's refresh the browser and take a look at the console. So I can see the request object has a property url as well as several others. url is exactly what I need. Now I'm going to store the URL in a local variable, then I'm going to add an if statement to check if the value matches the /date, in which case I'll respond with the date. Otherwise, I'll respond with the default response, 'Hello from Koa JS'.
Let's restart our server. Now I'll change the URL to have a /date and press enter. We see a date, kind of an ugly date, but it's the current date as expected. Now I'll get rid of the date part in the URL and press enter and we see 'Hello from Koa JS'.
Now let's change our logic a bit more. Let's say if the requested URL is just the root, we'll respond with 'Hello from Koa JS'. If the URL is /date, we'll provide the date, and if it's anything else, we'll send an HTTP status code 404.
Now I'll restart our server. Okay, first I'm going to check the root of the site and we see 'Hello from Koa JS' as expected. Next, I'll check with the URL /date and we see the date. Lastly, we will check some other URL. I will put my first name in here and we see our error message. Now to see the status code in Chrome, I need to open up the JavaScript console. To do that, I'll press Alt-Command-J and then I'll click on the Network tab. Now I have to hit refresh and I can see the 404 in the status code column.
Introduction to Middleware
Okay, so we interacted with the request object just a little bit and the response object just a little bit as well, but I'm not going to go much deeper at this point. You can look at the Koa JS web page to see all the options. It's a pretty easy read and of course you can always inspect the properties just as I did above.
Alright, so you're getting an idea of how you interact with the Koa JS server. However, this approach of using if-then checking the URLs is kind of ugly and will get out of hand pretty quickly. There's a much better approach using middleware, but before I show you the better approach, let's look at what middleware is, how you would write it, and use it in your app.
Think of middleware as a function that can do things between when a request is made and when the response is returned, thus the name 'in the middle'. A simple example that gives you a pretty good picture would be a middleware that adds the response time as a header to the response. Okay, so here's the format for middleware. You create a regular function that can take some setup options as a parameter, and that function returns a generator function which receives the next parameter. So in a nutshell, it's a function that returns a generator function.
Writing Custom Middleware: A Response Timer
Okay, to our example. I'm going to name my middleware function requestTime. It's going to take one parameter, which I'm labeling headerName. Now I'm going to return a generator function with the next parameter passed into that function. I'm going to start by storing the start date into the start variable. Then I'll yield control to downstream middleware using the syntax yield next.
This will pause execution of my middleware function and pass control to downstream middleware functions. After all downstream middleware has completed, my middleware will resume, at which point I'll store the ending date into the end variable. Then I'll calculate the difference from the start and the ending times, and lastly, I'll add this time in milliseconds as a header using the header name that was passed into the regular function.
All right, my middleware is done. However, I haven't actually told the app to use my middleware yet. To add this middleware, I'll pass my middleware into the app.use method. It's important that I add this middleware before the responding generator function, otherwise it will never get called. In other words, the sequence in which you add your middleware is significant.
Now let's restart the node server. In order to see the headers in Chrome, I have to have the developer tools open. If it's not open, I can press Alt-Command-J, then I'll click on the Network tab. Now let's go to the root and refresh the browser. If I click on the request, it will show the response headers and as you can see, it's been added near the bottom. Okay, that's pretty cool and uh, fairly straightforward.
Refactoring Routes with koa-router
Now let's look at a practical example of a piece of middleware that I can use to eliminate the if-then logic that I was using earlier. This should tidy things up quite a bit.
I'm going to use a middleware called koa-router. First I need to install it using npm install koa-router. Now I'll pull this module into my server, storing it into the router variable. Then I tell Koa to use this middleware by passing it to the use method, just as I did in my request time middleware.
This particular middleware calls for the Koa app to get passed into it because it's going to modify the properties on the app by adding a method for each possible HTTP method, such as get, post, put, patch, etc. Now I can get rid of the generator that has my if-then logic and instead answer the different requests by adding some routing rules. This is done by calling one of the new methods that the koa-router added to the app object, in this case the get method, passing in a string which is the pattern the router will use to match against the requested URL. And lastly, I'll pass in a generator function to handle the requests that match this particular pattern. Now I can repeat this pattern for each expected URL. So I will add a second app.get with the /date pattern passed in and a generator to handle these requests.
Now let's restart our nodejs server. Test out the route, and we see our 'Hello from Koa JS' message. Now let's test the date URL and we see our ugly date again. Lastly, let's look at a URL path that doesn't match our two parameters, and we see a 404 not found.
Conclusion and Next Steps
Okay, that's your quick start guide to building apps in Koa JS. The true power and utility in Koa JS is the use of generators, which gives you a better way to program asynchronously in JavaScript.
To learn more about generators, check out my screencast, 'Understanding JavaScript Generators', which will give you a deeper understanding of generators. Also stay tuned for a future screencast in which I'll create a full web application using Koa JS.
And lastly, please consider joining my mailing list at no.com/join so I can notify you when new screencasts are released as well as provide other valuable information. Thanks.
goodbye