Building a Node.js Express API with TypeScript, JWT Authentication, MongoDB, and Jest Testing

Building a Node.js Express API with TypeScript, JWT Authentication, MongoDB, and Jest Testing

In this article, we'll walk through the process of building a Node.js Express API using TypeScript while incorporating best practices, JWT (JSON Web Token) authentication, MongoDB for data storage, and Jest for testing. By the end of this tutorial, you'll have a foundational understanding of how to create a secure and robust API.

Prerequisites

Before we dive into building our API, make sure you have the following tools and libraries installed:

  • Node.js

  • npm or yarn

  • TypeScript

  • Express.js

  • MongoDB and Mongoose

  • Jest (for testing)

Setting Up the Project

We'll start by setting up our project. You can use the following package.json file as a template:

{
  "name": "nodejs-express-typescript-api",
  "version": "1.0.0",
  "description": "A Node.js Express API with TypeScript",
  "main": "index.js",
  "scripts": {
    "start": "ts-node src/app.ts",
    "test": "jest"
  },
  "dependencies": {
    // Dependencies here
  },
  "devDependencies": {
    // Dev dependencies here
  }
}

Project Structure

Here's the recommended project structure:

  • src/

    • app.ts: The main Express application file.

    • controllers/: Contains route controllers.

    • models/: Defines MongoDB data models.

    • middleware/: Houses authentication middleware.

    • routes/: Contains route definitions.

    • tests/: Stores Jest test files.

Implementing JWT Authentication

We'll create an authentication middleware that verifies JWT tokens. The middleware will be used in routes that require authentication. Here's a snippet of how you can implement it:

// src/middleware/auth.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

const secretKey = 'your-secret-key';

export const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
  const token = req.header('Authorization')?.replace('Bearer ', '');

  if (!token) {
    return res.status(401).json({ message: 'No token provided' });
  }

  jwt.verify(token, secretKey, (err, user) => {
    if (err) {
      return res.status(401).json({ message: 'Invalid token' });
    }

    req.user = user;
    next();
  });
};

Connecting to MongoDB

We'll use Mongoose to connect to a MongoDB database. Ensure you have your MongoDB URI and credentials ready:

// src/app.ts
import express from 'express';
import mongoose from 'mongoose';

const mongoURI = 'your-mongodb-uri';

mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true });

// Express app setup
const app = express();

// Additional app setup...

// Start the server...

Creating a Route and Controller

We'll create a sample route for creating a customer and its associated controller. This is just one example; you can expand this to include all your CRUD operations.

// src/routes/customer.ts
import express from 'express';
import { createCustomer } from '../controllers/customer';
import { authMiddleware } from '../middleware/auth';

const router = express.Router();

// Apply the authMiddleware to secure the route
router.post('/customers', authMiddleware, createCustomer);

export default router;
// src/controllers/customer.ts
import { Request, Response } from 'express';

export const createCustomer = async (req: Request, res: Response): Promise<void> => {
  try {
    // Implementation here...
  } catch (error) {
    res.status(500).json({ message: 'Internal server error' });
  }
};

Testing with Jest

Jest is a powerful testing framework for Node.js applications. We'll write tests for our controllers and routes to ensure our API is functioning as expected. Here's an example of how you can write a Jest test for creating a customer:

// src/tests/customer.test.ts
import request from 'supertest';
import app from '../app';

describe('Customer API', () => {
  it('should create a customer', async () => {
    // Test implementation...
  });
});

Conclusion

With these steps, you've created a Node.js Express API with TypeScript, JWT authentication, and MongoDB. You've also learned how to write tests for your API using Jest. This forms a strong foundation for building secure and efficient APIs.

Feel free to expand and customize your API according to your project requirements.

Also, I am leaving you a GitHub repository link here to check

Happy coding!