Building a Basic Todo List REST API in Node.js with Express
Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
Discover Express
"Express provides a thin layer of fundamental web application feature, without obscuring Node.js features that you know and love"
from expressjs.com
Before using Express, it has to be installed in the project using NPM.
NPM - The Node Package Manager
NPM is a tool shipped with Node.js that helps the user to manage packages of Node.js applications.
Here is a quick (non-exhaustive) recap of some of the main commands:
- npm init [-f|--force|-y|--yes] initializes your package and generates the package.json file
- npm install [--save | --save-dev | --save-optional| --save-optional]
- --save (default for npm 5.x), install your dependencies in your dependecies section of the package.json
- --save-dev, install a package and update the package.json but set the information in the devDependencies section
- --save-optional, install the dependency and update the package.json but set the information in optionalDependencies section
- npm uninstall , uninstall a package
- npm update [-g] [...], update npm version (globally)
- npm ls [[<@scope>/] ...] lists all the packages installed in the current directory
- npm search [search terms]
For more information, please see the official documentation
A quick word about packages
A package is a file or directory that is described by a package.json. This can happen in a bunch of different ways!
A package is any of the following:
a) a folder containing a program described by a package.json file
b) a gzipped tarball containing (a)
c) a url that resolves to (b)
d) a <name>@<version> that is published on the registry with (c)
e) a <name>@<tag> that points to (d)
f) a <name> that has a latest tag satisfying (e)
g) a git url that, when cloned, results in (a).
Noting all these package possibilities, it follows that even if you never publish your package to the public registry, you can still get a lot of benefits of using npm:
Install Express
Now, it's time for you to initialize the project and then to install express package in the Node.js application.
Project Structure
/
|
| - app.js
|
| - package.json
Please find below the content of the package.json file:
{
"name": "NodeTodoList",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.15.3"
}
}
The generated package.json contains as dependency the 'express' module in version "^4.15.3". The ^ is called a caret range. It says that express will be installed with a version that is compatible with 4.15.3
More Information on Dependencies Versions in Node.js
Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL.
See semver for more details about specifying version ranges.
version Must match version exactly
- >version Must be greater than version
- >=version etc
- <version
- <=version
- ~version "Approximately equivalent to version" See semver
- ^version "Compatible with version" See semver
- 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
- http://... See 'URLs as Dependencies' below
- ***** Matches any version
- "" (just an empty string) Same as *
- version1 - version2 Same as >=version1 <=version2.
- range1 || range2 Passes if either range1 or range2 are satisfied.
- git... use a git url as dependency
- ...
Hello World with Express
One of the key features of Express is that it gives you an easy way to route the request to the right handler function.
Using require('express') gives you a reference to a function that will create an Express application.
const express = require('express')
var app = express();
Now that we have create a new Express application, we can handle HTTP requests with:
app.METHOD(PATH, HANDLER)
Where:
- app is an instance of express.
- METHOD is an HTTP request method, in lowercase.
- PATH is a path on the server.
- HANDLER is the function executed when the route is matched.
Let's try it to create an handler that will treat a GET request on the '/' path.
Here are some informations about the commands used above:
- response.send([content]) adds the content to the response body. The content can be a Buffed object, a string or an Array.
- response.status(code) sets the HTTP status
- response.json([content]) sends a JSON response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify().
Building REST application
Express can help us to write a RESTfull API for our TodoList application:
- GET / retrieve the list of tasks
- POST / create a new task
- PUT /:id update the task of id id
- DELETE /:id
POST
To consume the message body of a request, there is an important subtlety to take into account: it's a stream.
When receiving a POST or PUT request, the request body might be important to your application. Getting at the body data is a little more involved than accessing request headers. The request object that's passed in to a handler implements the ReadableStream interface. This stream can be listened to or piped elsewhere just like any other stream. We can grab the data right out of the stream by listening to the stream's 'data' and 'end' events.
from https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
To consume all the chunks of the body, we have thus to listen for the 'data' event and retrieve each part of data. The 'end' event means that the entire body has been consumed.
DRY: use the parser-body module
Parsing a message body is such a common operation that there is already a middleware for that named body-parser:
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
Middleware functions can perform the following tasks:
- Execute any code.
- Make changes to the request and the response objects.
- End the request-response cycle.
- Call the next middleware function in the stack.
from http://expressjs.com/en/guide/using-middleware.html
var bodyParser = require('body-parser');
...
app.use(bodyParser.urlencoded({'extended':'true'})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
Now that we can handle body parsing, let's move on completing our RESTful api.
Now that we have started to build a REST API, let's move on how to use parameters.