Rest APIs - Express.js
by Tomas Trescak· APIs

0 / 1590 XP
The external project has not been reviewed yet
Please follow instructions below to submit your project

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:

Quick Start

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

💣🧠🏗️ SPOILERS: Solution

Let's imagine we're creating an API for managing tasks. We'll implement basic CRUD (Create, Read, Update, Delete) operations.

Setup Express.js (You can skip this if you are using our repository)

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

Create an Express App

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}`);
});

How This Works:

  • 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.

🚀 Running the Server:

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? 

🧪 Testing the Server

We will use the curl tool to test our brand new API! Please open a new terminal (command prompt).

🧪 Pending Tasks

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}
]

🧪 Adding Tasks

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!

🧪 Changing Tasks

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!

🧪 Deleting Tasks

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.

⚠️ Check

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.

Maggie

Discuss with Maggie
Use the power of generative AI to interact with course content

Maggie is a generative AI that can help you understand the course content better. You can ask her questions about the lecture, and she will try to answer them. You can also see the questions asked by other students and her responses.

Discuss with Others
Ask questions, share your thoughts, and discuss with other learners

Join the discussion to ask questions, share your thoughts, and discuss with other learners
Setup
React Fundamentals
10 points
Next.js
10 points
Advanced React
Databases
10 points
React Hooks
Authentication and Authorisation
10 points
APIs
CI/CD and DevOps
Testing React
Advanced Topics