next generation web framework for node.js
Presented by Michael Herman
GET
, POST
, PUT
, DELETE
GET
, POST
, PUT
, DELETE
$ whoamimichael.herman
$ whoamimichael.herman
Galvanize (since May 2015)...
$ whoamimichael.herman
Galvanize (since May 2015)...
By the end of this tutorial, you will be able to:
By the end of this tutorial, you will be able to:
By the end of this tutorial, you will be able to:
Set up a project with Koa using test driven development
Create a CRUD app, following RESTful best practices
Write integration tests
Write tests, and then write just enough code to pass the tests
By the end of this tutorial, you will be able to:
Set up a project with Koa using test driven development
Create a CRUD app, following RESTful best practices
Write integration tests
Write tests, and then write just enough code to pass the tests
Create routes with Koa Router
By the end of this tutorial, you will be able to:
Set up a project with Koa using test driven development
Create a CRUD app, following RESTful best practices
Write integration tests
Write tests, and then write just enough code to pass the tests
Create routes with Koa Router
Parse the request body with koa-bodyparser
Koa is a web framework for Node.js.
Koa is a web framework for Node.js.
Koa is a web framework for Node.js.
Lightweight - Although, it's developed 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.
Async/Await - 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.
Koa is a web framework for Node.js.
Lightweight - Although, it's developed 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.
Async/Await - 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.
Express-like: Since Koa has similar patterns to Express, it's relatively easy to pick up if you've worked at all with Express.
Koa is a web framework for Node.js.
Lightweight - Although, it's developed 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.
Async/Await - 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.
Express-like: Since Koa has similar patterns to Express, it's relatively easy to pick up if you've worked at all with Express.
For more on how Koa compares to Express, check out Koa vs Express.
Test Driven Development (TDD) is an iterative development cycle that emphasizes writing automated tests before writing the actual code.
Test Driven Development (TDD) is an iterative development cycle that emphasizes writing automated tests before writing the actual code.
Why?
Test Driven Development (TDD) is an iterative development cycle that emphasizes writing automated tests before writing the actual code.
Why?
Test Driven Development (TDD) is an iterative development cycle that emphasizes writing automated tests before writing the actual code.
Why?
movies
.We will be designing a RESTful API, using test driven development, for a single resource - movies
.
The API itself will follow RESTful design principles, using the basic HTTP verbs - GET, POST, PUT, and DELETE.
We will be designing a RESTful API, using test driven development, for a single resource - movies
.
The API itself will follow RESTful design principles, using the basic HTTP verbs - GET, POST, PUT, and DELETE.
URL | HTTP Verb | Action |
---|---|---|
/api/v1/movies | GET | Return ALL movies |
/api/v1/movies/:id | GET | Return a SINGLE movie |
/api/v1/movies | POST | Add a movie |
/api/v1/movies/:id | PUT | Update a movie |
/api/v1/movies/:id | DELETE | Delete a movie |
We will be designing a RESTful API, using test driven development, for a single resource - movies
.
The API itself will follow RESTful design principles, using the basic HTTP verbs - GET, POST, PUT, and DELETE.
URL | HTTP Verb | Action |
---|---|---|
/api/v1/movies | GET | Return ALL movies |
/api/v1/movies/:id | GET | Return a SINGLE movie |
/api/v1/movies | POST | Add a movie |
/api/v1/movies/:id | PUT | Update a movie |
/api/v1/movies/:id | DELETE | Delete a movie |
Clone down the base project:
$ git clone https://github.com/mjhea0/node-koa-api \ --branch v1 --single-branch$ cd node-koa-api
Clone down the base project:
$ git clone https://github.com/mjhea0/node-koa-api \ --branch v1 --single-branch$ cd node-koa-api
Check out the v1 tag to the master branch and install the dependencies:
$ git checkout tags/v1 -b master$ npm install
Clone down the base project:
$ git clone https://github.com/mjhea0/node-koa-api \ --branch v1 --single-branch$ cd node-koa-api
Check out the v1 tag to the master branch and install the dependencies:
$ git checkout tags/v1 -b master$ npm install
Run two quick sanity checks to make sure all is well:
$ npm startIt works!$ npm testSample Test ✓ should pass1 passing (8ms)
Clone down the base project:
$ git clone https://github.com/mjhea0/node-koa-api \ --branch v1 --single-branch$ cd node-koa-api
Check out the v1 tag to the master branch and install the dependencies:
$ git checkout tags/v1 -b master$ npm install
Run two quick sanity checks to make sure all is well:
$ npm startIt works!$ npm testSample Test ✓ should pass1 passing (8ms)
Take a quick look at the project structure before moving on.
Install Koa and Chai HTTP:
$ npm install koa@2.3.0 --save$ npm install chai-http@3.0.0 --save-dev
Install Koa and Chai HTTP:
$ npm install koa@2.3.0 --save$ npm install chai-http@3.0.0 --save-dev
Create a new file in the "test" directory called routes.index.test.js...
Add the code to routes.index.test.js
process.env.NODE_ENV = 'test';const chai = require('chai');const should = chai.should();const chaiHttp = require('chai-http');chai.use(chaiHttp);const server = require('../src/server/index');describe('routes : index', () => { describe('GET /', () => { it('should return json', (done) => { chai.request(server) .get('/') .end((err, res) => { res.status.should.eql(200); res.type.should.eql('application/json'); res.body.status.should.eql('success'); res.body.message.should.eql('hello, world!'); done(); }); }); });});
Run $ npm test
. The tests should fail.
Update src/server/index.js like so:
const Koa = require('koa');const app = new Koa();const PORT = 1337;app.use(async (ctx) => { ctx.body = { status: 'success', message: 'hello, world!' };});const server = app.listen(PORT, () => { console.log(`Server listening on port: ${PORT}`);});module.exports = server;
Update src/server/index.js like so:
const Koa = require('koa');const app = new Koa();const PORT = 1337;app.use(async (ctx) => { ctx.body = { status: 'success', message: 'hello, world!' };});const server = app.listen(PORT, () => { console.log(`Server listening on port: ${PORT}`);});module.exports = server;
Run the tests again. They should pass!
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.
$ npm install koa-router@7.2.1 --save
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.
$ npm install koa-router@7.2.1 --save
Create a new folder called "routes" within "server", and then add an index.js file to it:
const Router = require('koa-router');const router = new Router();router.get('/', async (ctx) => { ctx.body = { status: 'success', message: 'hello, world!' };})module.exports = router;
Update src/server/index.js:
const Koa = require('koa');const indexRoutes = require('./routes/index');const app = new Koa();const PORT = process.env.PORT || 1337;app.use(indexRoutes.routes());const server = app.listen(PORT, () => { console.log(`Server listening on port: ${PORT}`);});module.exports = server;
Essentially, we moved the /
route out of the main application file. Ensure the tests still pass before moving on.
Add a new route file called movies.js to "routes":
const Router = require('koa-router');const data = require('../data.json');const router = new Router();const BASE_URL = `/api/v1/movies`;module.exports = router;
Add a new route file called movies.js to "routes":
const Router = require('koa-router');const data = require('../data.json');const router = new Router();const BASE_URL = `/api/v1/movies`;module.exports = router;
Then, wire this file up to the main application in src/server/index.js:
const Koa = require('koa');const indexRoutes = require('./routes/index');const movieRoutes = require('./routes/movies');const app = new Koa();const PORT = process.env.PORT || 1337;app.use(indexRoutes.routes());app.use(movieRoutes.routes());const server = app.listen(PORT, () => { console.log(`Server listening on port: ${PORT}`);});module.exports = server;
Add a file called data.json to "src/server":
[ { "name": "The Land Before Time", "genre": "Fantasy", "rating": 7, "explicit": false }, { "name": "Jurassic Park", "genre": "Science Fiction", "rating": 9, "explicit": true }, { "name": "Ice Age: Dawn of the Dinosaurs ", "genre": "Action/Romance", "rating": 5, "explicit": false }]
Finally, add a new test file to "test" called routes.movies.test.js:
process.env.NODE_ENV = 'test';const chai = require('chai');const should = chai.should();const chaiHttp = require('chai-http');chai.use(chaiHttp);const server = require('../src/server/index');describe('routes : movies', () => {});
Start with a test:
describe('GET /api/v1/movies', () => { it('should return all movies', (done) => { chai.request(server) .get('/api/v1/movies') .end((err, res) => { should.not.exist(err); res.status.should.equal(200); res.type.should.equal('application/json'); res.body.status.should.eql('success'); res.body.data.length.should.eql(3); res.body.data[0].should.include.keys( 'id', 'name', 'genre', 'rating', 'explicit' ); done(); }); });});
To get the test to pass, add the route handler to src/server/routes/movies.js:
router.get(BASE_URL, async (ctx) => { try { ctx.body = { status: 'success', data: data }; } catch (err) { console.log(err) }})
To get the test to pass, add the route handler to src/server/routes/movies.js:
router.get(BASE_URL, async (ctx) => { try { ctx.body = { status: 'success', data: data }; } catch (err) { console.log(err) }})
Run the tests to ensure they pass.
Your turn!
Your turn!
Before, we add the tests and routes, we need to add koa-bodyparser, since Koa does not parse the request body by default.
$ npm install koa-bodyparser@4.2.0 --save
Add the requirement to src/server/index.js, and then make sure to mount the middleware to the app before the routes:
const Koa = require('koa');const bodyParser = require('koa-bodyparser');const indexRoutes = require('./routes/index');const movieRoutes = require('./routes/movies');const app = new Koa();const PORT = process.env.PORT || 1337;app.use(bodyParser());app.use(indexRoutes.routes());app.use(movieRoutes.routes());const server = app.listen(PORT, () => { console.log(`Server listening on port: ${PORT}`);});module.exports = server;
Your turn!
Your turn!
What's next?
What's next?
What's next?
Questions?
What's next?
Questions?
Well...
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |