Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nurmdrafi/d6abcdef8ad5dc582a2e73f3ab9cc44c to your computer and use it in GitHub Desktop.
Save nurmdrafi/d6abcdef8ad5dc582a2e73f3ab9cc44c to your computer and use it in GitHub Desktop.

Express.js Middleware Documentation

MongoDB Documentation

Building a Simple CRUD app with Node, Express, and MongoDB

Postman API testing by example

Connecting to a MongoDB database using Node.js

How to use CORS in Node.js with Express

Axios Documentation

React Query - Hooks for fetching, caching and updating asynchronous data in React

🎯 Initial Node Server Setup (express/mongodb)

  1. create folder structure (backend/frontend)
  2. npm init -y
  3. npm i express cors mongodb dotenv jsonwebtoken
  4. npm i -g nodemon
  5. create .gitignore insert node_modules and .env
  6. go to package.json
    "scripts": {
    "start": "node index.js",
    "start-dev": "nodemon index.js",
    }
  1. create index.js
// Basic
   const express = require("express");
   const app = express();
   const port = 5000;
   
   app.get("/users", async (req, res) => {
   res.send({message: "Hello Users"})
   })

   app.listen(port, () => {
        console.log("Listening to port", port);
    });
 // Standard
    const express = require("express");
    const app = express(); // create app by calling express()
    const cors = require("cors");
    const jwt = require('jsonwebtoken');
    const { MongoClient, ServerApiVersion } = require("mongodb");
    const ObjectId = require('mongodb').ObjectId;
    const port = process.env.PORT || 5000;
    
    require('dotenv').config();

    // use middleware
    app.use(cors()); // Allow access for two different port and server
    app.use(express.json()); // For parsing body of POST and PUT Method

    // for testing
    app.get("/", (req, res) => {
        res.send({ message: "Success" });
    });

    app.listen(port, () => {
        console.log("Listening to port", port);
    });
  1. nodemon index.js (run backend server)

🎯 Environment Variable Setup

  1. go to > dotenv guide - https://northflank.com/guides/connecting-to-a-mongo-db-database-using-node-js
  2. require('dotenv').config();
  3. create .env variable
  4. MONGO_URI=mongo+srv://<user>:<pass>@<host>:<port>/<database>?<connection options>
  • doesn't matter, using :-
    • whitespace between (=)
    • string
    • not using string
    • const uri = process.env.MONGO_URI;

🎯 MongoDB Setup

  1. sign up using google
  2. create user/pass (copy)
  3. network access > ip address: allow access from anywhere
  4. database > connect > connect your application > copy from include all
  5. paste in index.js (Server)
  6. replace with <password>
  7. comment // client.close()

🎯 Initialize CRUD operation

  1. paste async run function
  2. copy from mongodb initial setup connection
const uri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}@cluster0.iukjo.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
const client = new MongoClient(uri, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  serverApi: ServerApiVersion.v1,
});

async function run() {
  try {
    await client.connect();
    
    // Collections
    /*
    const myCollection = client.db(Database Name).collection(Collection Name [plural]);
    
    const productCollection = client.db("dewalt_DB").collection("products");
    const reviewCollection = client.db("dewalt_DB").collection("reviews");
    const orderCollection = client.db("dewalt_DB").collection("orders");
    const userCollection = client.db("dewalt_DB").collection("users");
    const paymentCollection = client.db("dewalt_DB").collection("payments");
    */
    
    app.get("/inventory", async (req, res) => { // Endpoint name must be singular
      const query = req.query;
      const cursor = myCollection.find(query);
      const result = await cursor.toArray();
      console.log("mongodb connected");
      res.send(result);
    });
  } finally {
    //   await client.close(); // do not forget to comment ✔
  }
}
run().catch(console.dir); // do not forget to call run ✔

// for testing
/*
app.get("/", (req, res) => {
res.send({ message: "Success" });
});
*/

app.listen(port, () => {
  console.log("Listening to port", port);
});

GET API ❄❄❄ Find Multiple Documents

Server

  app.get("/products", async (req, res) => {
  const query = req.query;
  const products = await productCollection.find(query).toArray();
  res.send(products);
  });

Client

  • using fetch
const [products, setProducts] = useState([]);
const [isReload, setIsReload] = useState(false); 

useEffect(() => {
  fetch("http://localhost:5000/products")
    .then((res) => res.json())
    .then((data) => setProducts(data));
}, [isReload]);
  • using Axios
useEffect(() => {
    const getItems = async () => {
      const url = "http://localhost:5000/products";
      const { data } = await axios.get(url);
      setIsLoading(false);
      setData(data);
    };
    getItems();
  }, []);
  • using React Query
const {
    isLoading,
    error,
    data: products,
    refetch,
  } = useQuery("products", () =>
    fetch("http://localhost:5000/products").then((res) =>
      res.json()
    )
  );
  if (isLoading) {
    return <Loading />;
  }

GET API ❄❄❄ Find a Document

Client

app.get("/products/:id", async (req, res) => {
const id = req.params.id;
const query = {_id: ObjectId(id)}
const product = await productCollection.findOne(query);
res.send(product);
});

Server

  • using fetch
  • using Axios
  • using React Query
    • jwt authorization
    • Implement 401 and 403
const {
    isLoading,
    error,
    data: product,
  } = useQuery("product", () =>
    fetch(`http:localhost:5000/products/${_id}`, {
      method: "GET",
      headers: {
        authorization: `Bearer ${localStorage.getItem("accessToken")}`,
      },
    }).then((res) => {
      if (res.status === 401 || res.status === 403) {
        signOut(auth);
        localStorage.removeItem("accessToken");
        navigate("/login");
      }
      return res.json();
    })
  );
  if (isLoading) {
    return <Loading />;
  }

POST API (create a single note) ❄❄❄

app.post("/note", async (req, res) => {
const data = req.body;
console.log(data); // testing
const result = await notesCollection.insertOne(data);
res.send(result)
});
  1. go to > Insert a Document - https://www.mongodb.com/docs/drivers/node/current/usage-examples/insertOne/#insert-a-document
  2. we will create a single data so endpoint should be single example: ("/note")
  3. get receive body data from req.body
  4. send post request from postman Body > raw > JSON
  5. console.log(data) for testing post data
  6. pass data into collection
  7. send result as a response
  8. copy and comment endpoint from postman to index.js

PUT API (update a single note) ❄❄❄

app.put("/note/:id", async (req, res) => {
    const id = req.params.id;
    const data = req.body;
    const filter = { _id: ObjectId(id) };
    const options = { upsert: true };
    const updateNote = {
      $set: {
        userName: data.userName,
        textData: data.textData
      },
      /* modify object using spread operator
      $set: {
        ...data
      },
      */
    };
    const result = await notesCollection.updateOne(filter, updateNote, options);
    res.send(result)
  });
  1. go to Update a Document
  2. use params in endpoint example ("/note/:id")
  3. get id from req.params.id
  4. here parameter need to be same
    • example: ("/note/:same_parameter" && req.params.same_parameter)
  5. console.log(id) // testing
  6. passing id from url using Postman
    • http://localhost:5000/note/62659010b03fcf637b79ebdd
  7. get receive body data from req.body
  8. console.log(data) // testing
  9. create a filter for update
    • require ObjectId and pass id parameter
  10. set option upsert: true:
    • if not exist add new value or if exist update
  11. set update object manually or using spread operator example ...data
  12. updateOne(filter, updateNote, options), parameters need to be placed serially
  13. send result as a response
  14. copy and comment endpoint from postman to index.js
  15. test GET, POST, PUT methods using Postman

DELETE API (delete a single note) ❄❄❄

app.delete("/note/:id" , async(req, res) =>{
  const id = req.params.id;
  const filter = { _id: ObjectId(id) };
  const result = await notesCollection.deleteOne(filter);
  res.send(result);
})
  1. go to Delete a Document - https://www.mongodb.com/docs/drivers/node/current/usage-examples/deleteOne/#delete-a-document
  2. get id from req.params.id
  3. create a filter for delete
    • set ObjectId and pass id parameter
  4. send result as a response
  5. test GET, POST, PUT, DELETE methods using Postman
  6. copy and comment endpoint from postman to index.js

🐼 Get all data from MongoDB

const [notes, setNotes] = useState([]);
const [isReload, setIsReload] = useState(false); 

useEffect(() => {
  // GET Method 🐼
  fetch("http://localhost:5000/notes")
    .then((res) => res.json())
    .then((data) => setNotes(data));
}, [isReload]);
  1. declare state for notes (all data)
  2. set isReload as a dependency for reload data after changes

🐼 Search by query parameter from MongoDB and display data setNotes(data)

const handleSearch = (e) => {
e.preventDefault();
const searchText = e.target.searchText.value;
// clear input
e.target.searchText.value = "";

if(searchText === ""){ // load all data when empty
  fetch("http://localhost:5000/notes")
  .then((res) => res.json())
  .then((data) => setNotes(data));
} else{
  fetch(`http://localhost:5000/notes?userName=${searchText}`)
  .then((res) => res.json())
  .then((data) => setNotes(data)); 
}
};
  1. search by query parameter from MongoDB
  2. display result by setNotes(data) ✔

🐼 Insert new data in MongoDB by POST Method and reload by setIsReload(!isReload)

const handlePost = (e) => {
e.preventDefault();
const userName = e.target.userName.value;
const textData = e.target.textData.value;

// clear input
e.target.userName.value = "";
e.target.textData.value = "";

fetch("http://localhost:5000/note", {
  method: "POST",
  headers: {
    "content-type": "application/json",
  },

  body: JSON.stringify({ userName, textData }),

  /* body:JSON.stringify({
    "userName": userName,
    "textData": textData
  }) */

}).then((res) => res.json());
// .then((data) => console.log(data));
setIsReload(!isReload); 
};
  1. insert new data by POST Method
  2. body set by manually or object literal also using spread operator at backend
  3. reload by setIsReload(!isReload) ✔
  4. here isReload fetch all data after changes

🐼 Delete data from MongoDB using DELETE Method and reload by setIsReload(!isReload)

const handleDelete = (id) => {
fetch(`http://localhost:5000/note/${id}`, {
  method: "DELETE",
});
setIsReload(!isReload);
};
  1. delete data from MongoDB using DELETE Method
  2. reload by setIsReload(!isReload) ✔
  3. here isReload fetch all data after changes

🐼 Update data using PUT Method and reload by setIsReload(!isReload)

const handleUpdate = (e) => {
e.preventDefault();
const userName = e.target.userName.value;
const textData = e.target.textData.value;
// clear input
e.target.userName.value = "";
e.target.textData.value = "";

fetch(`http://localhost:5000/note/${id}`, {
  method: "PUT",
  headers: {
    "content-type": "application/json",
  },
  body: JSON.stringify({ userName, textData }),

  /* body:JSON.stringify({
    "userName": userName,
    "textData": textData
  }) */

}).then((res) => res.json());
// .then((data) => console.log(data));
setIsReload(!isReload); 
};
  1. Update data using PUT Method
  2. reload by setIsReload(!isReload) ✔
  3. here isReload fetch all data after changes
  4. create custom hook is optional for [isReload, setIsReload]

🔥 Callback Function

  • (req, res)
    • req
      • client থেকে request receive করে।
    • req.body
      • req.body is actually key value pair json data from POST method
    body: JSON.stringify({
    title: 'foo',
    body: 'bar',
    userId: 1,
    })
    • req.query
      • query strings from URL
      • key value form
      • start after (?) mark
    • req.params.id
      • receive dynamic parameter from URL
      • endpoint using with /:id
      • endpoint parameter and req.params.parameter need to be same
      • require ObjectId and pass idParameter if update based on _id
    • res
      • request receive করার পর process করে client কে data send করে।
      • res.send(result)

🔥 API Naming Convention

app.get("/booking") // get all bookings in this collection, or get more than one by filter/query
app.get("/booking/:id") // get a specific booking(id)
app.post("/booking") // add new booking
app.patch("/booking/:id") // update specific booking(id)
app.delete("/booking/:id") // delete specific booking(id)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment