DEV Community

Emmanuel Kariithi
Emmanuel Kariithi

Posted on

How to build a user management API using Node.js and Express (No Database)

This tutorial will walk you through building a simple user management API that fetches data from a file as opposed to a database. With this API, you will be able to list all users, list one user, log in, Signup and Delete a user.

We are going to use node.js to build our server and bcryptjs to hash the passwords. This will be expanded in future to include a database.

What will be covered:

Setting Up the Project

  1. Create a new directory for your project and navigate to it using the command line.
  2. Initialize a new Node.js project by running npm init and following the prompts. You can also use npm init -y to skip the prompts.
  3. Install the necessary dependencies by running the following command: npm install express dotenv bcryptjs
    • Express is a web application framework that helps manage servers and routes.
    • Dotenv is a library that loads environment variables from a .env file into process.env.
    • Bcryptjs Is a library that helps one hash passwords.

At this point, you should have two files(package.json and package-lock.json) and the node_modules folder.

Inital Files

The package.json should have the three dependencies installed in step 3.

Dependencies

Creating the file structure

  1. Create a file called server.js as the entry point of your application.
  2. Create a directory called controllers to store your route handlers.
  3. Create a directory called routes to store your routes.
  4. Create a file called .env to store your environment variables. (Optional)
  5. Create a file called users.js to serve as the user data module.

File Structure

Setting up environment Variables Optional

  1. Open the .env file and define the necessary environment variables. For this project, we'll need the following variables: PORT=4000
  2. In the server.js file, require the dotenv package at the top:
require('dotenv').config();
Enter fullscreen mode Exit fullscreen mode
  1. Use process.env to access the environment variables throughout your application. For example, you can use process.env.PORT to retrieve the port number.

Creating the User Data Module

  1. In the users.js file, define an array variable to store the user data. Each user should have properties such as id, name, email, and password.
  2. Export the usersData array using module.exports so that it can be imported and used in other files.
const bcrypt = require('bcryptjs');

const usersData = [
  {
    id: 1,
    name: "John Doe",
    email: "john@example.com",
    password: bcrypt.hashSync("password123", 10)
  },
  {
    id: 2,
    name: "Jane Smith",
    email: "jane@example.com",
    password: bcrypt.hashSync("secret456", 10)
  },
  {
    id: 3,
    name: "Alice Johnson",
    email: "alice@example.com",
    password: bcrypt.hashSync("qwerty789", 10)
  },
  {
    id: 4,
    name: "Bob Williams",
    email: "bob@example.com",
    password: bcrypt.hashSync("pass1234", 10)
  },
  {
    id: 5,
    name: "Sarah Davis",
    email: "sarah@example.com",
    password: bcrypt.hashSync("password567", 10)
  }
];

module.exports = usersData;
Enter fullscreen mode Exit fullscreen mode

Creating the Express Application

  1. In the server.js file, require the necessary packages:
const express = require('express');
const usersRouter = require('./routes/usersRoutes');
Enter fullscreen mode Exit fullscreen mode
  1. Create an instance of the Express application:
const app = express();
Enter fullscreen mode Exit fullscreen mode
  1. Set up middleware to parse JSON request bodies:
app.use(express.json());
Enter fullscreen mode Exit fullscreen mode

server.js

require('dotenv').config();

const express = require('express');
const usersRouter = require('./routes/usersRoutes');


const app = express();
app.use(express.json());

app.use('/users', usersRouter);


const port = process.env.PORT || 4000;

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Creating the Controllers

  1. In the controllers directory, create a file called usersController.js to define the user-related controllers.
  2. Import the usersData module in your controller file using the require
const usersData = require('../users');
Enter fullscreen mode Exit fullscreen mode
  1. Define the controller functions for each endpoint. #### usersController.js
const usersData = require('../users');
const bcrypt = require('bcryptjs');

// Display all users
const getAllUsers = (req, res) => {
  const hashedUsers = usersData.map(user => ({
    ...user,
    password: bcrypt.hashSync(user.password, 10)
  }));
  res.json(hashedUsers);
};

// Display one user by ID
const getUserById = (req, res) => {
  const { id } = req.params;
  const user = usersData.find(user => user.id === parseInt(id));
  if (user) {
    const hashedUser = { ...user, password: bcrypt.hashSync(user.password, 10) };
    res.json(hashedUser);
  } else {
    res.status(404).json({ message: 'User not found' });
  }
};

// Login
const login = (req, res) => {
  const { email, password } = req.body;
  const user = usersData.find(user => user.email === email);
  if (user && bcrypt.compareSync(password, user.password)) {
    res.json({ message: 'Login successful' });
  } else {
    res.status(401).json({ message: 'Invalid credentials' });
  }
};

// Signup
const signup = (req, res) => {
  const { name, email, password } = req.body;
  const id = usersData.length + 1;
  const newUser = { id, name, email, password };
  usersData.push(newUser);
  res.status(201).json({ message: 'Signup successful' });
};

// Delete user by email
const deleteUserByEmail = (req, res) => {
  const { email } = req.params;
  const index = usersData.findIndex(user => user.email === email);
  if (index !== -1) {
    usersData.splice(index, 1);
    res.json({ message: 'User deleted successfully' });
  } else {
    res.status(404).json({ message: 'User not found' });
  }
};

module.exports = {
  getAllUsers,
  getUserById,
  login,
  signup,
  deleteUserByEmail
};
Enter fullscreen mode Exit fullscreen mode

Creating the Routes

  1. In the routes directory, create a file called usersRoutes.js to define the user-related routes.
  2. In the usersRoutes.js file, require the necessary packages.
const express = require('express');
const router = express.Router();
const usersController = require('../controllers/usersController');
Enter fullscreen mode Exit fullscreen mode
  1. Define the route handlers for each endpoint.
// Display all users
router.get('/', usersController.getAllUsers);

// Display one user by ID
router.get('/:id', usersController.getUserById);

// Login
router.post('/login', usersController.login);

// Signup
router.post('/signup', usersController.signup);

// Delete user by email
router.delete('/:email', usersController.deleteUserByEmail);
Enter fullscreen mode Exit fullscreen mode
  1. Export the router from the file.
module.exports = router;
Enter fullscreen mode Exit fullscreen mode

usersRoutes.js

const express = require('express');
const router = express.Router();
const usersController = require('../controllers/usersController');

// Display all users
router.get('/', usersController.getAllUsers);

// Display one user by ID
router.get('/:id', usersController.getUserById);

// Login
router.post('/login', usersController.login);

// Signup
router.post('/signup', usersController.signup);

// Delete user by email
router.delete('/:email', usersController.deleteUserByEmail);

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

Mounting the Routes in the Application

  • In the server.js file, mount the usersRouter to a base path.
app.use('/users', usersRouter);
Enter fullscreen mode Exit fullscreen mode
  • Start the server and listen for incoming requests.

    const port = process.env.PORT || 4000;
    
    app.listen(port, () => {
        console.log(`Server is running on port ${port}`);
        });
    

Testing the Endpoints using Postman

Let’s test the endpoints in Postman and verify that everything is working as intended.
Start the server by running node server.js or nodemon server.js

  • Display all users: Send a GET request to http://localhost:4000/users. This endpoint will return an array of all users, with hashed passwords.

Display all users

  • Display one user by ID: Send a GET request to http://localhost:4000/users/1 to retrieve the user with ID 1. This endpoint will return the user object with a hashed password. Replace 1 with the desired user ID.

Display one user by ID

  • Login: Send a POST request to http://localhost:3000/users/login with the following request body in JSON format:
  {
    "email": "jane@example.com",
    "password": "secret456"
  }
Enter fullscreen mode Exit fullscreen mode

Login

  • Signup: Send a POST request to http://localhost:4000/users/signup with the following request body in JSON format:
  {
    "name": "Jane Smith",
    "email": "jane@example.com",
    "password": "secret456"
  }
Enter fullscreen mode Exit fullscreen mode

Replace the values with the desired name, email, and password. If the signup is successful, the response will contain the message Signup successful.

SignUp

  • Delete a user by email: Send a DELETE request to http://localhost:4000/users/bob@example.com to delete the user with the email bob@example.com. Replace the email address with that of the user you want to delete. If the user exists, the response will contain the message User deleted successfully.

Delete a user by email

Congratulations! You have created and tested a user management API using Node.js, Express and Postman. The API will hash passwords and provide the specified endpoints for user management.

Top comments (0)