DEV Community

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

Posted on

2

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

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (4)

Collapse
 
mayowakalejaiye profile image
mayowa-kalejaiye

I came across your post again 😂. Awesome work on building the CRUD API with TypeScript and MongoDB! 🚀 Writing two APIs sounds like a lot, but you nailed it.

Quick question: Have you heard of soft delete? Instead of completely removing a user, it just marks them as deleted, so you can still recover or track the data later. Might be handy for future projects!

Keep it up—you’re doing great! 👏

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

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post