# Building a RESTful API With Koa and Postgres

In this tutorial, you’ll learn how to develop a RESTful API with Koa 2 and Postgres. You’ll also be taking advantage of async/await functions, from ES2017, and test driven development (TDD).

This tutorial requires Node v7.6.0 or greater.

#### NPM Dependencies

1. Koa v2.3.0
2. Mocha v3.5.0
3. Chai v4.1.1
4. Chai HTTP v3.0.0
5. Knex v0.13.0
6. pg v7.1.2
7. koa-router v7.2.1
8. koa-bodyparser v4.2.0

## Contents

1. Objectives
2. Getting Started
3. Project Setup
4. Routes
5. Next Steps

## Objectives

By the end of this tutorial, you will be able to…

1. Set up a project with Koa using test driven development
2. Write schema migration files with Knex to create new database tables
3. Generate database seed files with Knex and apply the seeds to the database
4. Set up the testing structure with Mocha and Chai
5. Perform the basic CRUD functions on a RESTful resource with Knex methods
6. Create a CRUD app, following RESTful best practices
7. Write integration tests
8. Write tests, and then write just enough code to pass the tests
9. Create routes with Koa Router
10. Parse the request body with koa-bodyparser

## Getting Started

### What are we building?

Your goal is to design a RESTful API, using test driven development, for a single resource - movies. The API itself should follow RESTful design principles, using the basic HTTP verbs: GET, POST, PUT, and DELETE.

### What is Koa?

Koa is a web framework for Node.js.

Although it’s designed by the same team that created Express, it’s much lighter than Express though - so it comes with very little out of the box. It’s really just a tiny wrapper on top of Node’s HTTP module. Koa allows you - the developer - to pick and choose the tools you want to use from the community.

It has native support for async/await, which makes it easier and faster to develop an API since you don’t have to deal with callbacks and callback hell.

Finally, since Koa has similar patterns to Express, it’s relatively easy to pick up if you’ve worked at all with Express.

NOTE: For more, review Koa vs Express.

### TDD

Test Driven Development (TDD) is an iterative development cycle that emphasizes writing automated tests before writing the actual code.

#### Why?

1. Helps break down problems into manageable pieces since you should have a better understanding of what you’re going to write
2. Forces you to write cleaner code
3. Prevents over coding

#### Red-Green-Refactor

TDD often follows the “Red-Green-Refactor” development cycle:

1. RED: Write a test, which should fail when you run it
2. GREEN: Write just enough code for the test to pass
3. REFACTOR: Refactor code and retest, again and again (if necessary)

## Project Setup

Start by cloning down the base project:

Then, check out the v1 tag to the master branch and install the dependencies:

Run two quick sanity checks to make sure all is well:

Take a quick look at the project structure before moving on.

### Koa

As always, we’ll begin with the obligatory hello world. But first, since we’re following TDD, let’s write a quick test.

Install Chai HTTP so we can test HTTP calls:

Create a new file in the “test” directory called routes.index.test.js:

So, within the second describe block, we have a single it statement, which defines a test case. In this simple case, we’re testing the response from a GET request to the main route, /.

Run the test via npm test. You should see the following error since the server is not setup:

Next, let’s stand up a quick Koa server. Install Koa:

Then, update src/server/index.js like so:

Here, we created a new instance of Koa and then mounted a basic async function to the app. This function takes the Koa context as a parameter, ctx. It’s worth noting that this object encapsulates both the Node request and response objects. We then set the return value to ctx.body, which will be sent back as the response body when user hits any route.

Run the Koa server, via npm start, and then navigate to http://localhost:1337/. You should see:

Once done, kill the server and then run the tests. They should now pass.

### Database

Moving right along, download and install Postgres, if you don’t already have it, and then fire up the server on port 5432.

Along with Postgres, we’ll use pg and Knex to interact with the database itself:

Install Knex globally as well so you can use the CLI tool:

Next, we need to create two new databases, one for our development environment and the other for test environment.

Open psql in the terminal, and create the databases:

With that, we can now initialize Knex.

### Knex

Run knex init in the project root to initialize a new config file called knexfile.js. Override the default info with:

NOTE: Make sure to replace username and password with your database username and password, respectively.

Next, let’s create a new migration to define the database schema:

This created a “src/server/db/migrations” folder with a timestamped migration file. Update the file like so:

Add a new file to the “db” folder called connection.js to, well, connect to the database using the appropriate Knex configuration based on the environment (development, test, staging, production, etc.):

Apply the migration to the development database:

Next, let’s create a seed file to populate the database with some initial data:

This added a seed file to “src/server/db/seeds”; update it to match the database schema:

Apply the seed:

Finally, hop back into psql to ensure the database has been updated:

### Koa Router

Unlike Express, Koa does not provide any routing middleware. There are a number of options available, but we’ll use koa-router due to its simplicity.

Create a new folder called “routes” within “server”, and then add an index.js file to it:

Then, update src/server/index.js:

Essentially, we moved the / route out of the main application file. Ensure the tests still pass before moving on.

## Routes

Again, we’ll take a test-first approach to writing our routes:

URL HTTP Verb Action
/api/v1/movies GET Return ALL movies
/api/v1/movies/:id GET Return a SINGLE movie
/api/v1/movies/:id PUT Update a movie
/api/v1/movies/:id DELETE Delete a movie

Before diving in, let’s add some structure. First, add a new folder called “queries” to the “db” folder, and then add a file called movies.js to that newly created folder:

We’ll add the database queries associated with the movies resource to this file. Next, add a new route file called movies.js to “routes”:

Then, wire this file up to the main application in src/server/index.js:

Finally, add a new test file to “test” called routes.movies.test.js:

So, when the tests are ran, the beforeEach() is fired before any of test specs, applying the migrations to the test database. After the specs run, the database is rolled back to a pristine state in the afterEach().

With that, let’s add our routes!

### GET All Movies

Take note of the code comments. Review Testing Node.js With Mocha and Chai for more info. Run the test to make sure it fails:

To get the test to pass, add the route handler to src/server/routes/movies.js:

Add the DB query to src/server/db/queries/movies.js:

So, getAllMovies() returns a promise object. Then, within the async function, execution stops at the await. Execution continues once the promise is resolved.

Run the tests to ensure they pass:

### GET Single Movie

What if we just want a single movie?

Make sure the test fails, and then add the route handler:

Don’t forget to export it:

The test should now pass. Before moving on though, what happens if the movie ID does not exist? Start with a test to find out.

Add an it block to the previous describe block:

Make sure the test fails before updating the code:

The test should now pass.

### POST

Koa does not parse the request body by default, so we need to add middleware for body parsing. koa-bodyparser is a popular choice:

Add the requirement to src/server/index.js, and then make sure to mount the middleware to the app before the routes:

DB query:

What if the payload does not include the correct keys? Add a new it block:

Then update the route handler:

### PUT

Test:

Route handler:

DB query:

Did you notice that we are already handling a case where the movie does not exist in the route handler? Let’s add a test for that:

### DELETE

Test:

Route handler:

Run the tests to ensure all pass:

## Next Steps

With that, you now have a basic Koa RESTful API up and running.

Test your knowledge by adding additional test cases and error handlers to cover anything missed. You may also want to convert an existing Express app over to Koa. Check out the Koa Examples repo for more code examples.