CRUD Operations Using a JSON File with Express.js

🚀 Introduction

CRUD stands for Create, Read, Update, and Delete. These are the four fundamental operations performed on data in most web applications. While production applications typically use databases, beginners can learn CRUD concepts by storing data in a JSON file. Express.js, along with Node.js's fs module, makes it easy to read from and write to JSON files.

Information

Using a JSON file as a data store is suitable for learning, prototypes, and small applications. For production applications, use a database such as MongoDB, MySQL, or PostgreSQL.

📋 Prerequisites

  • Node.js installed.
  • Express.js installed.
  • Basic knowledge of Express routing.
  • Basic understanding of JSON.

📁 Project Structure

express-app
data.json
index.js
package.json

📄 Creating the JSON File

Create a file named data.json to store user information.

data.json

[
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com"
  },
  {
    "id": 2,
    "name": "Bob",
    "email": "bob@example.com"
  }
]

📝 Setting Up the Express Server

index.js

const express = require('express');
const fs = require('fs');

const app = express();

app.use(express.json());

const FILE_PATH = './data.json';

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Tip

The express.json() middleware parses incoming JSON request bodies and makes them available through req.body.

📖 READ Operation

Retrieve all records from the JSON file.

GET /users

app.get('/users', (req, res) => {
  const data = JSON.parse(fs.readFileSync(FILE_PATH));

  res.json(data);
});

➕ CREATE Operation

Add a new user to the JSON file.

POST /users

app.post('/users', (req, res) => {
  const users = JSON.parse(fs.readFileSync(FILE_PATH));

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

  users.push(newUser);

  fs.writeFileSync(FILE_PATH, JSON.stringify(users, null, 2));

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

âœī¸ UPDATE Operation

Update an existing user's information using their ID.

PUT /users/:id

app.put('/users/:id', (req, res) => {
  const users = JSON.parse(fs.readFileSync(FILE_PATH));

  const user = users.find(
    user => user.id === Number(req.params.id)
  );

  if (!user) {
    return res.status(404).send('User not found');
  }

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

  fs.writeFileSync(FILE_PATH, JSON.stringify(users, null, 2));

  res.json(user);
});

🗑 DELETE Operation

Remove a user from the JSON file.

DELETE /users/:id

app.delete('/users/:id', (req, res) => {
  const users = JSON.parse(fs.readFileSync(FILE_PATH));

  const filteredUsers = users.filter(
    user => user.id !== Number(req.params.id)
  );

  fs.writeFileSync(
    FILE_PATH,
    JSON.stringify(filteredUsers, null, 2)
  );

  res.send('User deleted successfully.');
});

🔄 CRUD Workflow

Client
HTTP Request
HTTP Response
Express Server
Read JSON File
Perform CRUD Operation
Write Updated Data

📚 Request Lifecycle

📊 CRUD Endpoints

HTTP MethodEndpointOperation
GET/usersRetrieve all users.
POST/usersCreate a new user.
PUT/users/:idUpdate an existing user.
DELETE/users/:idDelete a user.

đŸ§Ē Example API Requests

Retrieve Users

GET /users

Create User

POST /users
Content-Type: application/json

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

Update User

PUT /users/2
Content-Type: application/json

{
  "name": "Bob Smith",
  "email": "bobsmith@example.com"
}

Delete User

DELETE /users/2

âš ī¸ Limitations of Using a JSON File

LimitationDescription
PerformanceThe entire file is read and written for each request.
ConcurrencySimultaneous writes can overwrite data.
ScalabilityNot suitable for large datasets.
Data IntegrityNo transactions or advanced consistency guarantees.

💡 Best Practices

  • Use express.json() to parse JSON request bodies.
  • Validate incoming request data before saving it.
  • Check whether a resource exists before updating or deleting it.
  • Use asynchronous file operations such as fs.promises in real-world applications to avoid blocking the event loop.
  • Use unique IDs instead of relying on the array length when creating new records.
  • Switch to a database as your application grows.

Best Practice

A JSON file is an excellent way to understand CRUD operations and Express.js routing. For production environments, replace file storage with a database to improve performance, scalability, and reliability.

📚 Learn More

Explore the official documentation:
â€ĸ Express.js Official Documentation
â€ĸ Node.js File System (fs) Module
â€ĸ MDN Web Docs - JSON

📝 Summary

Summary

CRUD operations using a JSON file provide a simple way to learn data management in Express.js. By combining Express routes with the Node.js fs module, you can create, read, update, and delete records stored in a JSON file. Although this approach is ideal for learning and small projects, production applications should use a dedicated database for better scalability and data integrity.