How to build a simple RESTful API with Node.js and Express: Managing Tasks
Introduction:
In Understanding a RESTful API for software integration, we talked about the principles, and best practices, in this article we are going to take it up a notch by building a restful API to manage tasks.
The Project:
We are going to build an API that allows users to:
Create Tasks: Add tasks to a server
Get a Task: Retrieve a specific task and its details
Update a Task: Make changes to a task
Delete a Task: Remove a task from a server
List Tasks: Get a list of all tasks
Tools and Technologies:
For this project, we will be using some tools:
Programming Language: Node.js with Express framework(a good way to learn how to work with Node and Express)
Data Storage: MongoDB.
Data Format: JSON for data formart & serialization
API Documentation: Swagger for API documentation
API Testing: Postman for API testing.
Implementation and Steps:
Follow these steps and start building(Make sure you create a directory for your project):
Setting up the project: This is the first step, and to do this it simply means initializing our Node.js project using:
npm init
, which will create a package.json file, after pressing the enter key and finally typing yes.npm init
After this install the Express.js, mongo, and body-parser(to parse incoming requests majorly as JSON) dependency:
npm install express
.npm install express mongoose body-parser
Create a new file in your project directory called server.js to set up our Express server.
Define Task Data Model:
Next, create a Models directory and then create a file called task.js to define the Task data model using Mongoose (“Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js. It helps developers to model their data, define the schema for documents inside a collection, and manage relationships between data” - Source Mongodb).
For this guide, we are using a remote Mongo database.
Create Task Routes:
Create a routes directory, and create a file in it called taskRoutes.js to define our APIs/Routes to perform the various functions.
Create task:
// Create a new task router.post('/v1/tasks', async (req, res) => { const task = new Task(req.body); try { await task.save(); res.status(201).send(task); } catch (error) { res.status(400).send(error); } });
Get all tasks and get tasks by ID:
// Get all tasks router.get('/v1/tasks', async (req, res) => { try { const tasks = await Task.find(); res.send(tasks); } catch (error) { res.status(500).send(error); } }); // Get a task by ID router.get('/v1/tasks/:id', async (req, res) => { const _id = req.params.id; try { const task = await Task.findById(_id); if (!task) { return res.status(404).send(); } res.send(task); } catch (error) { res.status(500).send(error); } });
Update and Delete a task by ID:
// Update a task by ID router.patch('/v1/tasks/:id', async (req, res) => { const updates = Object.keys(req.body); const allowedUpdates = ['description', 'completed']; const isValidOperation = updates.every((update) => allowedUpdates.includes(update) ); if (!isValidOperation) { return res.status(400).send({ error: 'Invalid updates!' }); } try { const task = await Task.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true, }); if (!task) { return res.status(404).send(); } res.send(task); } catch (error) { res.status(400).send(error); } }); // Delete a task by ID router.delete('/v1/tasks/:id', async (req, res) => { try { const task = await Task.findByIdAndDelete(req.params.id); if (!task) { return res.status(404).send(); } res.send(task); } catch (error) { res.status(500).send(error); } });
It should look like this:
Middleware and Documentation:
Here we will begin to parse our JSON in server.js.
const taskRoutes = require('./routes/taskRoutes');
app.use(express.json()); // Parse JSON requests
app.use(taskRoutes); // Use the task router
Add Swagger for API Documentation:
npm install swagger-jsdoc swagger-ui-express
After installation, create a swagger.js file to configure Swagger
Then update taskRoutes.js to include swagger documentation:
const swaggerJSDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
// ... (taskRoute code)
const options = {
swaggerDefinition: {
openapi: '3.0.0',
info: {
title: 'Task Manager API',
version: '1.0.0',
},
},
apis: ['./routes/*.js'], // Path to your routes files
};
const swaggerSpec = swaggerJSDoc(options);
router.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
Start the server and Test APIs
We’ll start the Express server:
node server.js
Then we’ll use Postman to test the API endpoints:
Create tasks using POST: /v1/tasks
List all tasks by using GET: /v1/tasks
List a task by using GET and the ID: /v1/tasks/:id
Update a task by using PUT: /v1/tasks/:id
Delete a task by using DELETE: /v1/tasks/id
POST method with a response from the server
GET method with a list of the tasks: