blog

Build a To-Do API With Node, Express, and MongoDB

API stands for Application Programming Interface. APIs allow the creation of an application to access features of an application or service. Building APIs with Node is very easy. Yes, you heard me right!

In this tutorial, you will be building a To-Do API. After you are done here, you can go ahead to build a front end that consumes the API, or you could even make a mobile application. Whichever you prefer, it is completely fine.

Application Setup

To follow this tutorial, you must have Node and NPM installed on your machine.

Before you start coding, you have to install MongoDB on your machine if you have not done that already. Here is a standard guide to help you in that area. Do not forget to return here when you are done.

Create the Todo Model

Create a folder called server, and inside it create another folder called models. This is where your Todo model will exist. This model will show how your Todo collection should be structured.

You create a new model by calling the model function of mongoose. The function receives two parameters: the name of the model as a string, and an object which contains the fields of the model. This is saved in a variable called Todo.

You create a text field for your to-do. The type here is String, and the minimum length is set at 1. You make it required so that no to-do record can be created without it. The trim option ensures that there are no white spaces when records are saved.

You create a field to save true of false value for each to-do you create. The default value is false.

Another field is created to save when the to-do is completed, and the default value is null.

You export the Todo module so it can be required in another file.

Set Up Mongoose

Inside your server folder, create another folder called db and a file called mongoose.js.

This file will be used to interact with your MongoDB, using Mongoose. Make it look like this.

Sets port to the port of the environment where the application will run or port 3000.

Sets up middleware to make use of bodyparser.

In the next part, you created the post request, passing in the path and a callback function which has request and response as its parameters.

In the block of code, you set todo to the text that is passed in the body of the request, and then call the save function on the todo. When the todo is saved, you send the HTTP response—this time, the todo. Otherwise, the status code 400 is sent, indicating an error occurred.

#server.js
...
// GET HTTP request is called on /todos path
app.get('/todos', (req, res) => {
// Calls find function on Todo
Todo.find().then((todos) => {
// Responds with all todos, as an object
res.send({todos})
// In case of an error
}, (e) => {
// Responds with status code of 400
res.status(400).send(e)
})
})
// GET HTTP request is called to retrieve individual todos
app.get('/todos/:id', (req, res) => {
// Obtain the id of the todo which is stored in the req.params.id
let id = req.params.id
// Validates id
if (!ObjectId.isValid(id)) {
// Returns 400 error and error message when id is not valid
return res.status(404).send('ID is not valid')
}
// Query db using findById by passing in the id retrieve
Todo.findById(id).then((todo) => {
// If no todo is found with that id, an error is sent
if (!todo) {
return res.status(404).send()
}
// Else the todo retrieve from the DB is sent.
res.send({todo})
// Error handler to catch and send error
}).catch((e) => {
res.status(400).send()
})
})
// HTTP DELETE request routed to /todos/:id
app.delete('/todos/:id', (req, res) => {
// Obtain the id of the todo which is stored in the req.params.id
let id = req.params.id
// Validates id
if (!ObjectId.isValid(id)) {
// Returns 400 error and error message when id is not valid
return res.status(404).send()
}
// Finds todo with the retrieved id, and removes it
Todo.findByIdAndRemove(id).then((todo) => {
// If no todo is found with that id, an error is sent
if (!todo) {
return res.status(404).send()
}
// Responds with todo
res.send({todo})
// Error handler to catch and send error
}).catch((e) => {
res.status(400).send()
})
})
// HTTP PATCH requested routed to /todos/:id
app.patch('/todos/:id', (req, res) => {
// Obtain the id of the todo which is stored in the req.params.id
let id = req.params.id
// Creates an object called body of the picked values (text and completed), from the response gotten
let body = _.pick(req.body, ['text', 'completed'])
// Validates id
if (!ObjectId.isValid(id)) {
// Returns 400 error and error message when id is not valid
return res.status(404).send()
}
// Checks if body.completed is boolean, and if it is set
if (_.isBoolean(body.completed) && body.completed) {
// Sets body.completedAt to the current time
body.completedAt = new Date().getTime()
} else {
// Else body.completed is set to false and body.completedAt is null
body.completed = false
body.completedAt = null
}
// Finds a todo with id that matches the retrieved id.
// Sets the body of the retrieved id to a new one
Todo.findOneAndUpdate(id, {$set: body}, {new: true}).then((todo) => {
// If no todo is found with that id, an error is sent
if (!todo) {
return res.status(404).send()
}
// Responds with todo
res.send({todo})
// Error handler to catch and send error
}).catch((e) => {
res.status(400).send()
})
})
// Listens for connection on the given port
app.listen(port, () => {
console.log(`Starting on port ${port}`)
})
// Exports the module as app.
module.exports = {app}

You have created HTTP methods covering all parts of your API. Now your API is ready to be tested. You can do test it using Postman. If you do not have Postman installed on your machine already, go ahead and get it from the Postman website.

Conclusion

In this tutorial, you learned how to build an API using Node. You made use of a lot of resources to make the API a powerful one. You implemented the necessary HTTP methods that are needed for CRUD operation.

JavaScript has become one of the de facto languages of working on the web. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato marketplace.

As you continue to build in Node, you will get to understand its power and the reason why it is used worldwide.