DEV Community

Cover image for Day 2 & 3: Building a simple CRUD API using Express and MongoDB
Hephzy
Hephzy

Posted on

Day 2 & 3: Building a simple CRUD API using Express and MongoDB

Hi Everyone!

It’s currently day 3 of the #100DaysofMiva challenge, and for the past two days, I’ve been working on building a CRUD API. While I created two versions of the API—one with Node.js and the other with TypeScript—this post will focus on the TypeScript API

TypeScript

I created an API which performs CRUD operations (Create, Read, Update, Delete).

db.js

I had connected my MongoDB database in this file, calling in my database URI from my .env file

const connect = async () => {
  try {
    if (!config.DB_URI) {
      throw new Error("DB_URI is undefined. Ensure that your .env file is configured correctly.");
    }

    await mongoose.connect(config.DB_URI);
    console.log('MongoDB connected');
  } catch (err) {
    if (err instanceof Error) { // Type narrowing
      console.error(err.message);
    } else {
      console.error("An unknown error occurred:", err);
    }
    process.exit(1);
  }
};

export default connect;
Enter fullscreen mode Exit fullscreen mode

Create

This endpoint allows the creation of new users and saves them to the database.

Code

const createUser = async (req: Request, res: Response) => {
  try {
    const { name, email } = req.body;

    if (!email || !name) {
      throw new Error('Email and name are required');
    }

    const check = await User.findOne({email});

    if (check) {
      throw Error('This user already exists');
    }
    const newUser = new User({ name, email });
    await newUser.save();

    res.status(201).json({ message: 'New user created', newUser})
  } catch (err) {
    if (err instanceof Error) { // Type narrowing
      console.error(err.message);
      res.status(400).json({ message: err.message});

    } else {
      console.error("An unknown error occurred:", err);
      res.status(500).json(err);
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Request

Route
POST http://localhost:4080/user/create

Payload Example

{
  "name": "Hephzy",
  "email": "hzdelight01@gmail.com"
}
Enter fullscreen mode Exit fullscreen mode

Responses

On a successful request, the API returns the created user’s details.

Response Example

Status Code: 201 Created

{
  "message": "New user has been created",
  "newUser": {
    "name": "Hephzy",
    "email": "hzdelight01@gmail.com",
    "_id": "66c7926c7457846bb26790a5"
  }
}
Enter fullscreen mode Exit fullscreen mode

Read

This endpoint retrieves a specific user from the database by email.

Code

async function getUser (req: Request, res: Response) {
  try {
    const { email } = req.body;

    if (!email) {
      throw new Error('Email is required');
    }

    const findUser = await User.findOne({ email });

    if (!findUser) {
      throw Error('User cannot be found')
    }

    res.status(200).json({ message: "Here is the user details:", findUser });
  } catch (err) {
    if (err instanceof Error) { // Type narrowing
      console.error(err.message);
      res.status(400).json({ message: err.message});

    } else {
      console.error("An unknown error occurred:", err);
      res.status(500).json(err);
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Request

Route
GET http://localhost:4080/user/get

Payload Example

{
  "message": "hzdelight01@gmail.com"
}
Enter fullscreen mode Exit fullscreen mode

Response

On success, the API returns user's details based on email.

Response Example

Status Code: 200 OK

{
  "message": "Here is the user details: ",
  "findUser": {
    "_id": "66c7926c7457846bb26790a5",
    "name": "Hephzy",
    "email": "hzdelight01@gmail.com",
    "__v": 0
  }
}
Enter fullscreen mode Exit fullscreen mode

Update

This endpoint updates an existing user's details, specifically the name, in the database.

Code

async function updateUser(req: Request, res: Response) {
  try {
    const { name, email } = req.body;

    if (!email || !name) {
      throw new Error('Email and name is required');
    }

    const find = await User.findOne({ email });

    if (!find) {
      throw Error('User not found');
    }

    const update = await User.updateOne({ name });
    res.status(200).json({
      message: 'Name has been updated'
    });
  } catch (err) {
    if (err instanceof Error) {
      console.error(err.message);
      res.status(400).json({ message: err.message});
    } else {
      console.error("An unknown error occurred:", err);
      res.status(500).json(err);
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Request

Route

PUT http://localhost:4080/user/update
Enter fullscreen mode Exit fullscreen mode

Payload Example

{
  "name": "Hephzibah",
  "email": "hzdelight01@gmail.com"
}
Enter fullscreen mode Exit fullscreen mode

Response

On success, the API returns the updated user object along with a status code of 200 (OK).

Response Example

Status Code: 200 OK

{
  "message": "User name has been updated"
}
Enter fullscreen mode Exit fullscreen mode

Delete

This endpoint deletes a user from the database.

Code

const deleteUser = async (req: Request, res: Response) => {
  try {
    const { email } = req.body;

    if (!email) {
      throw new Error('Email is required');
    }
    const find = await User.findOne({ email });

    if (!find) {
      throw Error('User not found')
    }

    const del = await User.deleteOne({ email });

    res.status(200).json({ message: 'User details has been deleted'});
  } catch (err) {
    if (err instanceof Error) {
      console.error(err.message);
      res.status(400).json({ message: err.message});
    } else {
      console.error("An unknown error occurred:", err);
      res.status(500).json(err);
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Request

Route

DELETE http://localhost:4080/user/delete
Enter fullscreen mode Exit fullscreen mode

Response

On success, the API returns a message confirming the deletion along with a status code of 200 (OK).

Response Example

Status Code: 200 OK

{
  "message": "User details has been deleted"
}
Enter fullscreen mode Exit fullscreen mode

I’ve got some projects coming up, and I’m sure many of them will need CRUD operations. So, I figured I’d knock this out all at once. I hope you had as much fun with this as I did! The only hiccup was how much time it took. Writing two APIs was a bit more of a marathon than I expected.

Anyway, if you want to check out the source code, it’s right here for you. Enjoy and happy coding!
CRUD API Day 2 and 3

Top comments (3)

Collapse
 
marvellye profile image
Ezekiel Marvellous

Ts is a breeze for you. Kudos 👏🏻🚀

Collapse
 
tobidelly profile image
TD!

Day 2 and 3 marathon.....

Collapse
 
mayowakalejaiye profile image
mayowa-kalejaiye

Brilliant