Build a Todo App with Node.Js, ExpressJs, MongoDB and VueJs - Part 1

In this tutorial, we will build a famous todo app with Node.Js using ExpressJs framework and MongoDB. Did I forget to tell you? The app will be API centric :).

The explosion of IoT has made developers start thinking API first, and before you wonder why I didn’t title this post “ Build a Todo App API with Node.Js ExpressJs, MongoDB, and VueJs”; I gotta tell ya, we’ll build the client in part two of this post using Vue.Js. In a nutshell, if you want to learn how to build API with Node.Js, grab a bottle of beer, this post is for you.

What is ExpressJs

ExpressJs simply put, it’s a web framework for Node.Js - stolen from the official docs . Taylor Otwell (Laravel’s creator) once said, “Developers build tools for developers”. ExpressJs was built for developers with the goal of simplifying Node APIs.

Project Structure

You are probably going to get a shock of your life when I tell ya we need not more than 4 files with relatively few lines of code to build this backend if you are new to Node.Js. To keep things simple, we’ll create just two folders.

  1. app folder: This houses our models, routes and the configuration file for the application.
  2. public folder: This will contain our dear public files like index.html page, images and css.

This structure is not the best for large projects and as you may have already figured out. You would run into maintainability issues on larger projects.

I will be sharing my opinion on structuring medium to large Node.Js projects if you would remain a darling and check back in two weeks for the post.

What you will need to install

  1. You will need Node
  2. You will need to install MongoDB

Application Packages

You should create a project folder at this point to house all the source code. I’ll call mine todo-app. This app depends on a couple of packages and will use npm to install them. Navigate to the project directory you just created and create a package. json file with the content below.

    "name": "node-todo",
    "version": "0.0.1",
    "description": "A simple todo application.",
    "main": "server.js",
    "author": "Samuel James",
    "dependencies": {
        "body-parser": "^1.5.2",
        "express": "~4.7.2",
        "method-override": "~2.1.2",
        "mongoose": "~3.6.2",
        "morgan": "^1.9.0"

Run npm install to install the dependencies.

Landing Page

We create a landing page in the public folder with this:


!DOCTYPE html>
    <meta charset="utf-8">
    <title>VueJS NodeJS and Express  Todo App</title>
    <h1>Todo App</h1>

App configuration file

Ofcourse, we’ll need to define some configurations like database connection parameters and what port the application should run on.

/todo-app/app/Config.js file with the following content

module.exports = {
  DB: 'mongodb://localhost:27017/todos', 
  APP_PORT: 4000

Todo Model

Model is an object representation of data in the database. So, we create a file at /todo-app/app/Todo.Js with the following:

var mongoose = require('mongoose')

// Define collection and schema for todo item
var todo = new mongoose.Schema({
  name: {
    type: String
  done: {
    type: Boolean
    collection: 'todos'

module.exports = mongoose.model('Todo', todo)

You notice we use mongoose for schema definition, right? Mongoose is an official MongoDB library built for manipulating MongoDB databases in Node. name: A name field for todo item done: Todo item status which is boolean


Every web application has at least an entry point. A route in web apps is more like saying: “Hey Jackson when I ask ya for this, give me that”. Same goes for our app, we’ll define what URL users need to access in order to get certain results or trigger certain actions.

In this case, we want users to be able to perform create, read, update and delete (CRUD) operations on todo items. We create a route file at /tod-app/app/Routes.js and update it with the following content:

'use strict'

var express = require('express')
var todoRoutes = express.Router()
var todo = require('./Todo')

// get all todo items in the db
todoRoutes.route('/all').get(function (req, res, next) {
  todo.find(function (err, todos) {
    if (err) {
      return next(new Error(err))

    res.json(todos) // return all todos

// add a todo item
todoRoutes.route('/add').post(function (req, res) {
      done: false
    function (error, todo) {
      if (error) {
        res.status(400).send('Unable to create todo list')

// delete a todo item

todoRoutes.route('/delete/:id').get(function (req, res, next) {
  var id =
  todo.findByIdAndRemove(id, function (err, todo) {
    if (err) {
      return next(new Error('Todo was not found'))
    res.json('Successfully removed')

// update a todo item

todoRoutes.route('/update/:id').post(function (req, res, next) {
  var id =
  todo.findById(id, function (error, todo) {
    if (error) {
      return next(new Error('Todo was not found'))
    } else { =
      todo.done = req.body.done{
        function (error, todo) {
          if (error) {
            res.status(400).send('Unable to update todo')
          } else {

First, you would want users to get a list of all to-do items existing in the database, hence we defined a route (/all) that accepts a get request and returns a JSON object of todo items if successful.

Our users like to get items as well as store new items, we added a route to create new to-do items. It accepts a post request. When Mr. A makes a post request to route (/add), a new to-do item is created in the database.

Once a todo-item is completed, we also want users to be able to mark it as done. To do this, one must know what item a user intends to mark as done in the first place. So, we defined an ‘update route’ with a route parameter which is the ID of the item to update.

Server File

Having defined all routes that our application needs, it is time to create an entry file which is the main file to run our project.

At the project root folder, create a server.js file and update it with this:

/* jslint node: true */
'use strict'

var express = require('express')
var morgan = require('morgan')
var path = require('path')
var app = express()
var mongoose = require('mongoose')
var bodyParser = require('body-parser')

// Require configuration file defined in app/Config.js
var config = require('./app/Config')
// Connect to database
// Sends static files  from the public path directory
app.use(express.static(path.join(__dirname, '/public')))

// Use morgan to log request in dev mode
app.use(bodyParser.urlencoded({extended: true}))
var port = config.APP_PORT || 4000
app.listen(port) // Listen on port defined in config file

console.log('App listening on port ' + port)
var todoRoutes = require('./app/Routes')
//  Use routes defined in Route.js and prefix with todo
app.use('/api', todoRoutes)
app.use(function (req, res, next) {
    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:' + port)
    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE')
    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type')
    // Pass to next layer of middleware
// Server index.html page when request to the root is made
app.get('/', function (req, res, next) {

We required:

We set our app to listen on the port set in app/Config.js. if it’s not set, it defaults to 4000. We also tell it to use routes defined in app/Routes.js and prefix with api.

To start the application, navigate to project root where server.js file is located and run node server.js

Let’s create a new todo item

$ curl -H "Content-Type: application/json" -X POST -d '{"name":"Going Shopping"}' http://localhost:4000/api/add

{"__v":0,"name":"Going Shopping","done":false,"_id":"5a6365a39a2e56bc54000003"}

Get all todo items

$ curl  http://localhost:4000/api/all

[{"_id":"5a6365a39a2e56bc54000003","name":"Doing Laundry","done":false,"__v":0},{"_id":"5a6366039a2e56bc54000004","name":"Going Shopping","done":false,"__v":0}]

Get the source code here