How to build a user management API using Node.js and Express (No Database)
Tags: api, node, express
Published: 2023-06-14 19:17:43

---
title: How to build a user management API using Node.js and Express (No Database)
published: true
description: 
tags: #api #nodejs #express
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-06-14 16:50 +0000
---

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](#setting-up-the-project)
- [Creating the file structure](#creating-the-file-structure)
- [Setting up environment Variables Optional](#setting-up-environment-variables-optional)
- [Creating the User Data Module](#creating-the-user-data-module)
- [Creating the Express Application](#creating-the-express-application)
- [Creating the Controllers](#creating-the-controllers)
- [Creating the Routes](#creating-the-routes)
- [Mounting the Routes in the Application](#mounting-the-routes-in-the-application)
- [Testing the Endpoints using Postman](#testing-the-endpoints-using-postman)

### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tulwnumx01rykwfd20c3.png)

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

![Dependencies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbcmmaaq9qot3i8lzxx2.png)

### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbwfmhosulu7s1fw8dn4.png)

### 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: 
```js 
require('dotenv').config();
```
3. 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.
```js
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;
```

### Creating the Express Application
1. In the `server.js` file, require the necessary packages:
```js
const express = require('express');
const usersRouter = require('./routes/usersRoutes');
```

2. Create an instance of the Express application:
```js
const app = express();
```
3. Set up middleware to parse JSON request bodies: 
```js 
app.use(express.json());
```

#### server.js
```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}`);
});
```
### 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 
```js
const usersData = require('../users');
```
2. Define the controller functions for each endpoint.
#### usersController.js
```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
};
```

### 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.
```js
const express = require('express');
const router = express.Router();
const usersController = require('../controllers/usersController');
```
3. Define the route handlers for each endpoint.
```js
// 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);
```
4. Export the router from the file.
```js
module.exports = router;
```

#### usersRoutes.js
```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;
```

### Mounting the Routes in the Application
- In the `server.js` file, mount the usersRouter to a base path.
```js
app.use('/users', usersRouter);
```
- Start the server and listen for incoming requests.
    ```js
    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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6f0yo9rj4g4b9bkqsla.png)

- **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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12grqywetn28l9v4okkj.png)

- **Login:** Send a POST request to `http://localhost:3000/users/login` with the following request body in JSON format:
  ```json
  {
    "email": "jane@example.com",
    "password": "secret456"
  }
  ```
![Login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7mztcpcdwdamnfqca4r.png)

- **Signup:** Send a POST request to `http://localhost:4000/users/signup` with the following request body in JSON format:
  ```json
  {
    "name": "Jane Smith",
    "email": "jane@example.com",
    "password": "secret456"
  }
  ```
Replace the values with the desired name, email, and password. If the signup is successful, the response will contain the message ***Signup successful***.

![SignUp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zj6oujjongyhetcxdi27.png)

- **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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r28y8d5155mdhftq3oax.png)

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.