Skip to main content

Command Palette

Search for a command to run...

Building a Secure REST API with Node.js and Express

Updated
โ€ข4 min readโ€ขView as Markdown
A
Hi, Iโ€™m Ajnas, a web developer and digital marketing enthusiast from Kerala, India. I enjoy building web applications, experimenting with new technologies, and turning ideas into useful products. My main interests include JavaScript, Node.js, Express, React, PostgreSQL, MongoDB, SEO, and digital marketing. On this blog, I share what I learn, the projects I build, technical experiments, and practical lessons from my journey as a developer. Always learning. Always building. ๐Ÿš€

Modern web applications often depend on APIs to communicate between the frontend, backend, and databases. Whether you're building a dashboard, mobile application, or SaaS product, understanding how REST APIs work is an important backend skill.

In this article, we'll build a simple REST API using Node.js and Express.js, while following a structure that can later be extended with authentication and a database.

What We're Building

Our API will have endpoints for managing users:

GET     /api/users
GET     /api/users/:id
POST    /api/users
PUT     /api/users/:id
DELETE  /api/users/:id

The basic architecture looks like this:

Client
  โ”‚
  โ–ผ
Express Server
  โ”‚
  โ”œโ”€โ”€ Routes
  โ”‚
  โ”œโ”€โ”€ Controllers
  โ”‚
  โ”œโ”€โ”€ Middleware
  โ”‚
  โ–ผ
Database
  1. Create the Project

Start by creating a new Node.js project:

mkdir node-rest-api cd node-rest-api npm init -y

Install Express:

npm install express

For development, you can also install Nodemon:

npm install --save-dev nodemon 2. Create the Server

Create an app.js file:

const express = require("express");

const app = express(); const PORT = 3000;

app.use(express.json());

app.get("/", (req, res) => { res.json({ message: "API is running ๐Ÿš€" }); });

app.listen(PORT, () => { console.log(Server running on port ${PORT}); });

Run it:

node app.js

Visit:

http://localhost:3000

You should get:

{ "message": "API is running ๐Ÿš€" } 3. Create Some Data

For now, we'll use an array instead of a database.

let users = [ { id: 1, name: "Ajnas", email: "ajnas@example.com" }, { id: 2, name: "John", email: "john@example.com" } ]; 4. GET All Users

We can create an endpoint that returns all users:

app.get("/api/users", (req, res) => { res.json(users); });

Request:

GET /api/users

Response:

[ { "id": 1, "name": "Ajnas", "email": "ajnas@example.com" }, { "id": 2, "name": "John", "email": "john@example.com" } ] 5. GET a Single User

Route parameters allow us to retrieve a specific user.

app.get("/api/users/:id", (req, res) => { const id = Number(req.params.id);

const user = users.find(user => user.id === id);

if (!user) {
    return res.status(404).json({
        message: "User not found"
    });
}

res.json(user);
});

Now:

GET /api/users/1

returns:

{ "id": 1, "name": "Ajnas", "email": "ajnas@example.com" }

6. Creating a User

For creating resources, we use POST.

app.post("/api/users", (req, res) => { const { name, email } = req.body;

if (!name || !email) {
    return res.status(400).json({
        message: "Name and email are required"
    });
}

const newUser = {
    id: users.length + 1,
    name,
    email
};

users.push(newUser);

res.status(201).json(newUser);

});

The request body:

{ "name": "Charlie", "email": "charlie@example.com" }

The API responds with:

{ "id": 3, "name": "Charlie", "email": "charlie@example.com" }

7. Updating a User

We can use PUT to update an existing resource:

app.put("/api/users/:id", (req, res) => { const id = Number(req.params.id);

const user = users.find(user => user.id === id);

if (!user) {
    return res.status(404).json({
        message: "User not found"
    });
}

user.name = req.body.name ?? user.name;
user.email = req.body.email ?? user.email;

res.json(user);

});

This lets us update only the fields we provide.

  1. Deleting a User

Finally, we can implement DELETE:

app.delete("/api/users/:id", (req, res) => { const id = Number(req.params.id);

const exists = users.some(user => user.id === id);

if (!exists) {
    return res.status(404).json({
        message: "User not found"
    });
}

users = users.filter(user => user.id !== id);

res.json({
    message: "User deleted successfully"
});

}); A Better Project Structure

Once an application grows, keeping everything inside app.js becomes difficult.

A more maintainable structure could look like:

node-rest-api/
โ”‚
โ”œโ”€โ”€ controllers/
โ”‚   โ””โ”€โ”€ userController.js
โ”‚
โ”œโ”€โ”€ routes/
โ”‚   โ””โ”€โ”€ userRoutes.js
โ”‚
โ”œโ”€โ”€ middleware/
โ”‚   โ””โ”€โ”€ errorHandler.js
โ”‚
โ”œโ”€โ”€ models/
โ”‚   โ””โ”€โ”€ userModel.js
โ”‚
โ”œโ”€โ”€ app.js
โ”œโ”€โ”€ package.json
โ””โ”€โ”€ .env

This separation makes the application easier to maintain and extend.

What's Next?

The array we're using isn't suitable for a real production application.

The next step would be connecting the API to a database such as PostgreSQL or MongoDB.

From there, we could add:

Database
   โ†“
Authentication
   โ†“
Authorization
   โ†“
Input Validation
   โ†“
Error Handling
   โ†“
Rate Limiting
   โ†“
Logging
   โ†“
Production Deployment

That's where a simple REST API starts becoming a real backend application.

Final Thoughts

Building a REST API is one of those projects that looks simple at first but teaches a lot about backend development.

You learn how HTTP methods work, how requests and responses are structured, how routing works, how to handle errors, and eventually how different parts of a backend application communicate.

I'm still exploring backend development myself, and projects like this are helping me understand what happens behind the interface of the applications we use every day.

More of my projects and experiments:

ajnasahammed.com

More from this blog

C

Code With Ajnas

2 posts

Welcome to my corner of the internet. I document my journey as a developer, sharing what I learn, the projects I build, bugs I encounter, and lessons along the way. I write about web development, JavaScript, Node.js, React, databases, APIs, SEO, digital marketing, and building digital products. Learn, build, experiment, and grow with me.

Build. Break. Learn. Repeat.