Express + Mongo Simplified

spacerambler

Keely

Posted on September 2, 2021

Express + Mongo Simplified

More notes I was taking in class to capture the steps to use Mongo DB and express routes... WIP

*File List: *
package.json
.env
config.js
index.js
routes.js
controller.js

Getting started, we are using the zoo database.

Because we have everything installed, Mongo is always running in the background

package.json

Will need to add the following:
*express
*mongodb
*dotenv

.env

Copy string from mongosh and add to this file.
Also add the port number here.

config.js

Use this file to connect the env with the rest of the application, export

import dot env from 'dotenv';
dotenv.config();
export default {
port: process.env.PORT || 3000,
db: proces.env.DB_CLIENT_URL
};
Enter fullscreen mode Exit fullscreen mode

If the port number is not provided in env file, it will default to 3000 (aka short circuit pattern).

Next, import config into index.js

loader.js

Use this to set up the mongo client & export it out.

import { MongoClient } from "mongodb";
import config from "./config.js";

const client = new MongoClient(config.db);

client
  .connect()
  .then(() => {
    console.info("Connected to MongoDB");
  })
  .catch((err) => {
    console.error("Error starting MongoDB Client");
    process.exit(1);
    // using "1" as exit code because it's not a graceful exit
    // using "0" as exit code because it's a graceful exit
  });

process.on("SIGINT", () => {
  client.close().then(() => {
    console.info("MongoDB connection closed");
    process.exit(0);
  });
});

export default client;
Enter fullscreen mode Exit fullscreen mode

index.js

*import
*declare
*get path, call back
*listen
... everything between localhost:3000/ and localhost:3000/api

routes.js

*import
*declare
*get path, call back
*use

controller.js

Creating a method that connects to the database collection we want to use... then import it into routes.js

const controller = {
async index()
 {
const animals = await client.db("zoo")
.collection("animals")
.find()
.toArray();
return animals;
}}
Enter fullscreen mode Exit fullscreen mode

.find creates a cursor that allows us to go into the array and do stuff like filter or sort.
We can pass in a parameter into the index() that will allow us to use the fields in the routes... will need to interpolate using a bracket when calling it.

routes.js

create a route that gets all the animals
http://localhost:3000/animals

import animalsController from "./controller.js"
router.get("/animals", async (_, res)=>{
const animals = await animalsController.index();
res.json(animals);
}
Enter fullscreen mode Exit fullscreen mode

Create a route that sorts by a field
http://localhost:3000/animals?sort=class
In the route we will add the parameters into the path and then we'll need to interpolate that parameter in the controller.

const controller = {
async index(sortBy)
 {
const animals = await client.db("zoo")
.collection("animals")
.find()
.sort({ name: 1 })
.toArray();
return animals;
}}
Enter fullscreen mode Exit fullscreen mode

And then we'll need to update the router to include the sort parameter

import animalsController from "./controller.js"
router.get("/animals", async (req, res)=>{
const animals = await animalsController.index(req.query.sort);
res.json(animals);
}
Enter fullscreen mode Exit fullscreen mode

CRUD Routes

FROM HERE WE STARTED USING A NEW DATABASE FOR A NOTE TAKER APP
Mongo DB is going to create a new collection dynamically. Won't need to set anything up beforehand since we already have everything connected in the .env.

First, need to add json middleware to index.js

import morgan from "morgan"
app.use(morgan("dev"))
app.use(express.json());
Enter fullscreen mode Exit fullscreen mode

Morgan logs the routes in node

Mount the routes

import apiRouter from "./router.js"
app.use("/api", apiRouter)
Enter fullscreen mode Exit fullscreen mode

POST

Starting the post route to create a new note
http://localhost:3000/api/

router.post("/", (req, res)=>{
res.json(req.body);
});
Enter fullscreen mode Exit fullscreen mode

Practicing iterative coding...
Go back to the controller.

import client from "./loader.js";
export default {
 create(newNote) {
return client.db("noteTaker").collection("notes").insertOne(newNote);
}
}
Enter fullscreen mode Exit fullscreen mode

Then add controller to routes file.

import noteController from "./controller.js"
router.post("/", (req, res)=>{
const newNote = await noteController.create(req.body);
res.json(req.body);
});
Enter fullscreen mode Exit fullscreen mode

Add in try/catch for errors in the route

router.post("/notes", async (req, res)=>{
try {
const newNote = await noteController.create(req.body);
res.json(req.body);
} catch (error) {
rest.status(400).json(error.message)
}
});
Enter fullscreen mode Exit fullscreen mode

GET

Prints all the notes in the database.

Starting with the routes:

router.get("/notes", async (req, res) => {
try {
const notes = await noteController.index();
res.json(notes)
} catch (error) {
res.state(400).json(error.message)}
}
Enter fullscreen mode Exit fullscreen mode

then add to the controller...
This file is using the mongo db library of methods.
Link to those methods

import client from "./loader.js";
export default {
index() {
return notesConnection.find({}).toArray();
},
 create(newNote) {
return client.db("noteTaker").collection("notes").insertOne(newNote);
}
}
Enter fullscreen mode Exit fullscreen mode

GET

Print 1 note (instead of all the notes)
In the controller we can use .findOne(id)

show(id) {
return notesConnection.findOne(ObjectId(id));
}
Enter fullscreen mode Exit fullscreen mode

Adding to routes, we'll need to use a dynamic path. We'll also need to add in params

router.get("/notes/:id", async (req, res) => {
try {
const note = await noteController.show(req.params.id);
res.json(note);
} catch(error) {
res.status(400).send(error);
}
})
Enter fullscreen mode Exit fullscreen mode

DELETE

Delete a note... going to skip the routes since this is a review.
In the controller, we'll need to use .deleteOne and pass in the id as an object.

delete(id) {
 return notesConnection.deleteOne({ _id: ObjectId(id) });
}
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
spacerambler
Keely

Posted on September 2, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related