Express.js is a popular framework for building web applications and APIs in Node.js. Follow this simple example of how to create a REST API handler using Express:
Please fork and clone the following repository and try to make all unit tests happy! If you finish, check out the solution below!
https://github.com/WesternSydneyUniversity/comp3036-api-express
Let's imagine we're creating an API for managing tasks. We'll implement basic CRUD (Create, Read, Update, Delete) operations.
First, make sure you have Node.js and NPM installed. Initialise a new Node.js project and install Express.js by running:
mkdir MyProject
cd MyProject
pnpm init
pnpm i express
In the project directory, create the following file app.ts
import express from 'express';
const app = express();
// Middleware to parse JSON bodies
app.use(express.json());
// In-memory data store for tasks
let tasks = [
{ id: 1, description: 'Complete the project report', completed: false },
{ id: 2, description: 'Clean the house', completed: true }
];
// GET /tasks - Get a list of all tasks
app.get('/tasks', (req, res) => {
res.json(tasks);
});
// GET /tasks/:id - Get a single task by ID
app.get('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const task = tasks.find(t => t.id === taskId);
if (task) {
res.json(task);
} else {
res.status(404).json({ message: 'Task not found' });
}
});
// POST /tasks - Create a new task
app.post('/tasks', (req, res) => {
const newTask = {
id: tasks.length + 1,
description: req.body.description,
completed: req.body.completed || false
};
tasks.push(newTask);
res.status(201).json(newTask);
});
// PUT /tasks/:id - Update a task by ID
app.put('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex !== -1) {
const updatedTask = {
id: taskId,
description: req.body.description,
completed: req.body.completed
};
tasks[taskIndex] = updatedTask;
res.json(updatedTask);
} else {
res.status(404).json({ message: 'Task not found' });
}
});
// DELETE /tasks/:id - Delete a task by ID
app.delete('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex !== -1) {
tasks.splice(taskIndex, 1);
res.json({ message: 'Task deleted' });
} else {
res.status(404).json({ message: 'Task not found' });
}
});
// Start the server
const port = 3000;
app.listen(port, () => {
console.log(`API server running on http://localhost:${port}`);
});
GET /tasks: Retrieves all tasks.
GET /tasks/:id: Retrieves a task by its unique ID.
POST /tasks: Adds a new task to the list.
PUT /tasks/:id: Updates an existing task with the provided data.
DELETE /tasks/:id: Deletes a task by its unique ID.
To start the server, simply run the following command in the project directory:
node app.mjs
You should see a following message:
API server running on http://localhost:3000
You can now test the updated endpoints with tools like Postman or curl. This will allow you to manage tasks with the new REST API setup.
Why app.mjs and nod app.js? We are using the “new” import notation and not a commonjs notation that has been a standard for many years. The “import” notation is the new standar and with *.mjs extension we are telling node.js that we are using it. The other option is to specify type: “module in your package.json. In this case all files are considered to me new ”import" modules. Confusing … huh?
We will use the curl tool to test our brand new API! Please open a new terminal (command prompt).
First, let's check what tasks we have pending:
curl http://localhost:3000/tasks
You should see the following response:
[
{"id":1,"description":"Complete the project report","completed":false},
{"id":2,"description":"Clean the house","completed":true}
]
To add a task using the API via curl, you'll need to send a POST request with the appropriate JSON payload to the /task endpoint. Here's an example:
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"description": "Write API documentation", "completed": false}'
Explanation:
-X POST: Specifies that the request is a POST request.
http://localhost:3000/tasks: This is the endpoint where the request will be sent.
-H "Content-Type: application/json": This header indicates that the request body is in JSON format.
-d '{...}': This option allows you to specify the data (payload) to be sent in the body of the request.
Your response should look as the following:
{
"id":3,
"description":"Write API documentation",
"completed":false
}
👾 Exercise: Try to retrieve the list of tasks again!
To change a task to complete using curl, you will send a PUT request to update the task's completed status. In this example, I will assume we're updating the task with an ID of 1 (adjust the ID based on your actual task ID).
curl -X PUT http://localhost:3000/tasks/1 \ -H "Content-Type: application/json" \ -d '{"description": "Write API documentation", "completed": true}'
Explanation:
-X PUT: Specifies that the request is a PUT request (used for updates).
http://localhost:3000/tasks/1: This is the endpoint where the request will be sent, and it targets the task with ID 1.
-H "Content-Type: application/json": This header indicates that the request body is in JSON format.
-d '{...}': This option specifies the data (payload) to be sent in the body of the request. Here, we're updating the task's description and setting completed to true.
Make sure the description field matches the existing task's description or provide a new one. The task's completed status will be updated to true to mark it as completed.
👾 Exercise: Try to retrieve the list of tasks again!
To delete a task using curl, you'll need to send a DELETE request to the specific task's endpoint. Here's an example, assuming we want to delete the task with an ID of 1 (adjust the ID to match the task you want to delete):
curl -X DELETE http://localhost:3000/tasks/2
Explanation:
-X DELETE: Specifies that the request is a DELETE request.
http://localhost:3000/tasks/1: This is the endpoint that targets the task with ID 1.
After sending this command, you should receive a confirmation message indicating that the task was successfully deleted.
Try running the following command:
First, let's check what tasks we have pending:
curl http://localhost:3000/tasks
Did you get the following response?
[
{"id":1,"description":"Write API documentation","completed":true},
{"id":3,"description":"Write API documentation","completed":false}
]
If so, next, we'll transform this Express.js application to Next.js application.