# Connecting with MongoDB & Mongoose

Connecting to MongoDB using Mongoose in a Node.js application is a common task when working with data-driven applications. Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js, providing a straightforward way to model your data, manage relationships, and perform schema validation. This detailed guide will walk you through the entire process of setting up a Node.js project, connecting to a MongoDB database, and performing basic CRUD operations using Mongoose.

### Prerequisites

Before we start, ensure you have the following installed on your system:

1. **Node.js**: Download and install from [Node.js official site](https://nodejs.org/).
2. **MongoDB**: Download and install from [MongoDB official site](https://www.mongodb.com/try/download/community).
3. **MongoDB Atlas (optional)**: If you prefer using a cloud-based MongoDB service, sign up at [MongoDB Atlas](https://www.mongodb.com/cloud/atlas).

### Step 1: Setting Up Your Node.js Project

1. **Create a project directory**:

   ```bash
   mkdir mongoose-nodejs-tutorial
   cd mongoose-nodejs-tutorial
   ```
2. **Initialize a new Node.js project**:

   ```bash
   npm init -y
   ```
3. **Install necessary packages**:

   * **Express**: A web application framework for Node.js.
   * **Mongoose**: An ODM for MongoDB.

   ```bash
   npm install express mongoose
   ```

### Step 2: Connecting to MongoDB

#### Using a Local MongoDB Instance

1. **Start your MongoDB server**:

   ```bash
   mongod
   ```
2. **Create a new file `app.js` in your project directory**:

   ```javascript
   const express = require('express');
   const mongoose = require('mongoose');

   const app = express();
   const port = 3000;

   // Replace with your MongoDB URI
   const mongoURI = 'mongodb://localhost:27017/mongoose_tutorial';

   mongoose.connect(mongoURI, {
     useNewUrlParser: true,
     useUnifiedTopology: true
   }).then(() => {
     console.log('Connected to MongoDB');
   }).catch(err => {
     console.error('Error connecting to MongoDB', err);
   });

   app.get('/', (req, res) => {
     res.send('Hello World!');
   });

   app.listen(port, () => {
     console.log(`Server is running on http://localhost:${port}`);
   });
   ```

#### Using MongoDB Atlas

1. **Set up MongoDB Atlas**:
   * Go to [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) and create an account.
   * Create a new cluster and get the connection string.
2. **Update the `mongoURI` in `app.js`**:

   ```javascript
   const mongoURI = 'your_atlas_connection_string';
   ```

### Step 3: Defining a Mongoose Schema and Model

Create a new directory `models` and add a file `User.js`:

```javascript
const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  age: {
    type: Number,
    required: true,
  }
});

const User = mongoose.model('User', userSchema);

module.exports = User;
```

### Step 4: CRUD Operations

#### Create (Insert) a User

Update `app.js` to include a route for creating users:

```javascript
const User = require('./models/User');
app.use(express.json()); // For parsing application/json

app.post('/users', async (req, res) => {
  try {
    const user = new User(req.body);
    await user.save();
    res.status(201).send(user);
  } catch (error) {
    res.status(400).send(error);
  }
});
```

#### Read (Fetch) Users

Add a route to get all users:

```javascript
app.get('/users', async (req, res) => {
  try {
    const users = await User.find();
    res.status(200).send(users);
  } catch (error) {
    res.status(500).send(error);
  }
});
```

#### Update a User

Add a route to update a user by ID:

```javascript
app.patch('/users/:id', async (req, res) => {
  try {
    const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
    if (!user) {
      return res.status(404).send();
    }
    res.send(user);
  } catch (error) {
    res.status(400).send(error);
  }
});
```

#### Delete a User

Add a route to delete a user by ID:

```javascript
app.delete('/users/:id', async (req, res) => {
  try {
    const user = await User.findByIdAndDelete(req.params.id);
    if (!user) {
      return res.status(404).send();
    }
    res.send(user);
  } catch (error) {
    res.status(500).send(error);
  }
});
```

### Step 5: Running the Application

1. **Start your Node.js server**:

   ```bash
   node app.js
   ```
2. **Test your API**:
   * Use tools like [Postman](https://www.postman.com/) to test the endpoints (`POST /users`, `GET /users`, `PATCH /users/:id`, `DELETE /users/:id`).

Congratulations! You have successfully set up a Node.js application, connected it to MongoDB using Mongoose, and implemented basic CRUD operations. This setup forms a solid foundation for building more complex applications with robust data management capabilities.
