MQ
QURASHI
Blog
MQ
MOHAMED QURASHI

© 2026 Mohamed Qurashi. All rights reserved.

Built with precisionDesigned for impactPowered by innovation
MQ
QURASHI
Blog
Back to Blog
Backend

Building APIs with Node.js and Express

Mohamed Qurashi
December 5, 2024
18 min read
Building APIs with Node.js and Express

Share

TwitterFacebookLinkedIn

Tags

Node.jsExpressAPIBackend

Building robust APIs is a fundamental skill for modern web developers. Node.js and Express provide an excellent foundation for creating scalable, maintainable RESTful APIs. This guide covers everything you need to know.


Setting Up Your Project


Initialize Project

npm init -y

npm install express dotenv cors helmet

npm install -D nodemon


Project Structure

Organize your API with a clear structure:

project/

├── src/

│ ├── controllers/

│ ├── models/

│ ├── routes/

│ ├── middleware/

│ ├── utils/

│ └── app.js

├── .env

└── package.json


Basic Express Setup


const express = require('express');

const app = express();


// Middleware

app.use(express.json());

app.use(express.urlencoded({ extended: true }));


// Routes

app.get('/api/health', (req, res) => {

res.json({ status: 'OK', timestamp: new Date() });

});


const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {

console.log(`Server running on port ${PORT}`);

});


RESTful API Design


Follow REST principles:

  • **GET**: Retrieve resources
  • **POST**: Create new resources
  • **PUT**: Update entire resources
  • **PATCH**: Partial updates
  • **DELETE**: Remove resources

  • Example CRUD Operations


    // GET all items

    app.get('/api/items', async (req, res) => {

    try {

    const items = await Item.find();

    res.json(items);

    } catch (error) {

    res.status(500).json({ error: error.message });

    }

    });


    // POST create item

    app.post('/api/items', async (req, res) => {

    try {

    const item = new Item(req.body);

    await item.save();

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

    } catch (error) {

    res.status(400).json({ error: error.message });

    }

    });


    Middleware


    Error Handling

    app.use((err, req, res, next) => {

    console.error(err.stack);

    res.status(500).json({

    error: 'Something went wrong!',

    message: process.env.NODE_ENV === 'development' ? err.message : undefined

    });

    });


    Authentication

    const authenticate = (req, res, next) => {

    const token = req.headers.authorization?.split(' ')[1];

    if (!token) {

    return res.status(401).json({ error: 'Unauthorized' });

    }

    // Verify token

    next();

    };


    Best Practices


    1. Input Validation

    Use libraries like Joi or express-validator:

    const { body, validationResult } = require('express-validator');


    app.post('/api/users',

    body('email').isEmail(),

    body('password').isLength({ min: 8 }),

    (req, res) => {

    const errors = validationResult(req);

    if (!errors.isEmpty()) {

    return res.status(400).json({ errors: errors.array() });

    }

    // Process request

    }

    );


    2. Rate Limiting

    Prevent abuse with rate limiting:

    const rateLimit = require('express-rate-limit');


    const limiter = rateLimit({

    windowMs: 15 * 60 * 1000, // 15 minutes

    max: 100 // limit each IP to 100 requests per windowMs

    });


    app.use('/api/', limiter);


    3. Security Headers

    Use Helmet.js for security:

    const helmet = require('helmet');

    app.use(helmet());


    4. CORS Configuration

    const cors = require('cors');

    app.use(cors({

    origin: process.env.ALLOWED_ORIGINS?.split(',') || '*',

    credentials: true

    }));


    Database Integration


    MongoDB with Mongoose

    const mongoose = require('mongoose');


    mongoose.connect(process.env.MONGODB_URI, {

    useNewUrlParser: true,

    useUnifiedTopology: true

    });


    const ItemSchema = new mongoose.Schema({

    name: { type: String, required: true },

    description: String,

    price: Number

    }, { timestamps: true });


    const Item = mongoose.model('Item', ItemSchema);


    Testing Your API


    Use tools like:

  • **Postman**: Manual testing
  • **Jest**: Unit and integration tests
  • **Supertest**: API endpoint testing

  • Documentation


    Document your API with:

  • OpenAPI/Swagger
  • Postman collections
  • README with examples

  • Building great APIs requires attention to security, performance, and developer experience. Follow these practices to create APIs that are both powerful and maintainable.