Quick Guide | MERN Stack Application Development
Tags: webdev, react, mongodb, node
Published: 2024-06-04 20:29:17

Developing a full-stack application offers a comprehensive understanding of application architecture. In this article, we will explore the development process of a full-stack application using the MERN stack, one of the most popular tech stacks today. This article will provide a hands-on guide for the steps to build a MERN stack application from scratch.
This article will aim to be as concise as possible to focus on providing an overview. So, let's get started!!🚀

### Introduction
This tutorial will begin with setting up the server using Node.js and Express.js (Step 1), connecting to MongoDB (Step 2), and creating APIs (Steps 3 and 4). Next, we will work on the frontend with React.js to retrieve data through the server and render it in the browser (Steps 5 and 6)

####File structure

- frontend (folder)

- backend (folder)

- config.env

- .gitignore (_*to ignore .env and node_modules_)

### Step1 : Set up server with Node.js
Go to backend folder
```
$ cd backend
```
Create json file to set up server
```
$ npm init
```
Install packages
```
$ npm install express cors
```
Create index.js in backend folder and configure server
```
import express from "express";
const app = express();
const PORT = 5500;

app.use(cors());
app.use(express.json());
app.listen(PORT, () => {
  console.log(`APP is listning to port :${PORT}`);
});
```
Make sure package.json file contains below;
I recommend using nodemon.
```
 "type": "module",
 "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  },
```
Then, run the npm
```
$ npm run start
```
or
```
$ npm run dev
```
Finally, you will get
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hh7mwzpvcps64ju6a105.png)


### Step2 : Connect mongoDB
Firstly, go to mongoDB website and create a cluster.

Install dependencies. 
_*'dotenv' is used to retrieve environment variables from an env file. This helps to hide passwords and API keys (such as the MongoDB password) when you push this project to a public repository on GitHub. Any information in the env file is ignored by Git in this case._
```
$ npm install mongoose dotenv
```
Write mongoDB password on config.env
```
PASSWORD=************
```
In index.js,
```
import mongoose from "mongoose";
import dotenv from "dotenv";
dotenv.config({ path: "../config.env" });
.....
mongoose
  .connect( `mongodb+srv://<YOUR USER NAME>:${process.env.PASSWORD}@cluster0.jwm7sal.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0`,
    {}
  )
  .then(() => {
    console.log("connected with DB successfully!");
  })
  .catch((error) => {
    console.log(error);
  });
```
If you're connected with mongoDB, you will see the console message 'connected with DB successfully!!'. Congratulation🎉

### Step3 : Define Data model and create API
In this step, you will write code to interact with DB. In this tutorial, folders are divided into the following three;
- model : to define schema
- route : to define endpoint
- controller : to define function (action) based on particular HTTP request
Then, the folder structure looks like;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33j4iuff8ojloi1j80kd.png)

##### model
Under the model folder, create testModel.js;
```
import mongoose from "mongoose";
//   Shcema
const Schema = mongoose.Schema;
const testSchema = new Schema({
  name: String,
  age: Number,
});
export const Testmodel = mongoose.model("Testmodel", testSchema);
```
##### route
Under the route folder, create testRoute.js;
```
import express from "express";
import * as testController from "../controller/testController.js";
// Define route to execute it
const router = express.Router();
router.get("/", testController.readTests);
router.post("/", testController.createTest);
export default router;
```
##### controller
Under the controller folder, create testController.js. All the handlings related to the test collection are here.
```
import { Testmodel } from "../model/testModel.js";

export const createTest = async (req, res) => {
  try {
    const newTest = await Testmodel.create(req.body);
    res.status(201).json({
      status: "success",
      data: {
        newTest,
      },
    });
  } catch (err) {
    res.status(400).json({
      status: "fail",
      message: err,
    });
  }
};

export const readTests = async (req, res) => {
  try {
    const docs = await Testmodel.find({});
    res.status(201).json({
      status: "success",
      data: {
        docs,
      },
    });
  } catch (err) {
    res.status(400).json({
      status: "fail",
      message: err,
    });
  }
};
```
Then, give an endpoint which is corresponding to this collection at index.js
```
import testRoute from "./route/testRoute.js";
.....
app.use("/test", testRoute);
```
### Step 4 : Examine if the API is working
To examine it, this tutorial uses Postman as an API platform.
##### test 1 : Create a document
Send HTTP post request like below picture and document is now successfully created.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qzmti3wzgcnnjjc156z.png)
The new document can also be seen on Mongo Atlas;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3ldxjtiw2z4e2xq7yse.png)
##### test 2 : Read documents
Likewise, the documents are read.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/950lgpmg762hp33ii2vg.png)

Now that we've done the simplest setting up for server & DB. Next, let's build frontend.

### Step 5 : Set up React.js
At your root file, create and start react by the command below
```
$ npx create-react-app frontend
$ cd frontend
$ npm start
```
(clean up default code on App.js, for the sake of simplicity)

### Step 6 : Interact with server
Once react is activated, let's try to connect with the server. Firstly, install axios.
```
$ npm i axios
```
Then, at your App.js, import axios and react Hooks;
```
import React, {useState, useEffect} from "react";
import axios from "axios";
```
Tap the API we created in Step3 by using useEffect. The retrieved data is stored in the state.
```
const [testArr, setTestArr] = useState("");

useEffect(() => {
    axios
      .get(`http://localhost:5500/test`)
      .then((res) => {
        setTestArr(res.data.data.docs);
      })
      .catch(console.log("failed"));
  }, []);
```
Then, try to render it.
```
  return (
    <>
      <p>{testArr[0].name}</p>
      <p>{testArr[0].age}</p>
    </>
  );
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzh1o3kxpu72e515z8jf.png)

Now the frontend is connected with the server we created and the data is successfully rendered. 

This tutorial ends here, but the possibilities for creating your own applications are endless, thanks to i.e. the versatile React Hooks and the flexibility of MongoDB. I hope this provides a clear and comprehensive overview of building an app with the MERN stack.