#100DaysOfMERN - Day 28

#100DaysOfMERN - Day 28

·

8 min read

✏ Connecting to MongoDB (without Mongoose) from a Server

This is going to be a quick exploration of how to process HTTP requests to perform CRUD operations on the database.

One thing ahead: I might not explore "how to use mongodb without mongoose" for very long, because I found it difficult to discover good resources. Mongoose has been around for more than 10 years, and I feel like I'm trying to dig out some long-forgotton wisdom of the ancients here.

For simplicity, I'll keep it all in my file withoutMongoose.js, which right now looks like this (removing the hardcoded insertOne operation, and making some minor changes to include a .then/.catch chain):

const mongoClient = require('mongodb').MongoClient;

const connStr = 'mongodb://localhost/merndb';

const connOptions = {
  useNewUrlParser: true,
  useUnifiedTopology: true
};

mongoClient.connect(connStr, connOptions)
    .then((client) => {
        const db = client.db();
        console.log('mongo connected')

    }).catch(err => console.log(err))

Here, db is an object that gives me some methods to interact with the database.

✏ Setting up a basic server

I'll use express for this:

npm install express

Bringing it into the script, and testing it with a simple GET request:

const express = require('express');
const mongoClient = require('mongodb').MongoClient;

const app = express();
app.use(express.json());

app.get('/', (req, res) => res.end('Server is Serving'));

app.listen(5000, ()=>console.log('server is serving on port 5000'))

Alright, that works. Now I'd like to change that first route, so that the server serves back some data from the database, so again - make sure that mongo is running in the background. I'll also restructure the above code a little, because I don't want the server to listen for requests, unless the connection to the database is successful:

const express = require('express');
const mongoClient = require('mongodb').MongoClient;

// server
const app = express();
app.use(express.json());

// db connection
const connStr = 'mongodb://localhost/merndb';
const connOptions = {
  useNewUrlParser: true,
  useUnifiedTopology: true
};

mongoClient.connect(connStr, connOptions)
    .then((client) => {
        const db = client.db();
        console.log('mongo connected')

        app.get('/', (req, res) => res.end('Server is Serving'));

        app.listen(5000, ()=>console.log('server is serving on port 5000'))

    }).catch(err => console.log(err))

I actually have no clue if my code makes sense. I've moved the .get route into the connection callback, because it'll need access to the database object db, but this looks really weird. I mean it works. I just wonder if throwing all my routes in there will lead to particularly readable code. But anyway, now for the GET request:

✏ GET request to the database

I already know how to get all entries in a collection with the Shell:

db.posts.find()

However, this doesn't work, I'll have to replace that with:

db.collection('posts').find()

Sending that back in the response however still doesn't work, because what comes back from the .find method is a pointer (called cursor). In the Shell, the .find method automatically iterates over the cursor, but as I'm now accessing the method from a driver, I'll have to do that manually, for example with a forEach loop:

const cursor = db.collection('posts').find();

const posts = [];
cursor.forEach(item => posts.push(item))
    .then(() => res.json(posts));

There's an easier method toArray though, so my GET request now looks like this:

mongoClient.connect(connStr, connOptions)
    .then((client) => {
        const db = client.db();
        console.log('mongo connected')

        app.get('/', (req, res) => {
            db.collection('posts').find()
                .toArray()
                .then(posts => res.json(posts))
        });

        app.listen(5000, ()=>console.log('server is serving on port 5000'))

    }).catch(err => console.log(err))

I'll stop here, because I'm not sure if I'm going anywhere with this, but at some point I'd like to return to this - and really understand the Mongo Driver interface. If you're interested in how to make POST/PUT/DELETE requests similar to this, I'll leave the link to an article below. It doesn't explain much about the why/what, but shows you the how.


✏ Resources

MongoDB without Mongoose


✏ Recap

I've learned

  • how to make a GET request to my database from a local server
  • MongoDB without Mongoose is complicated

✏ Next:

  • MongoDB with Mongoose

✏ Thanks for reading!

I do my best to thoroughly research the things I learn, but if you find any errors or have additions, please leave a comment below, or @ me on Twitter. If you liked this post, I invite you to subsribe to my newsletter. Until next time 👋


✏ Previous Posts

  • Day 1: Introduction, Node.js, Node.js in the terminal
  • Day 2: npm, node_modules, package.json and package-lock.json, local vs global installation of packages
  • Day 3: Create a React app without create-react-app, Webpack, Babel
  • Day 4: npx and cowsay
  • Day 5: npm vs. npx, npm audit, semantic versioning and update rules
  • Day 6: Call stack, event loop, JavaScript engine, JavaScript runtime
  • Day 7: Call stack and event loop in Node.js, setImmediate()
  • Day 8: setImmediate(), process.nextTick(), event loop phases in Node.js
  • Day 9: Network requests with XMLHttpRequest and callbacks
  • Day 10: Promises
  • Day 11: Network requests with XMLHttpRequest and Promises
  • Day 12: React Quiz App part 1
  • Day 13: React Hangman
  • Day 14: FullStackOpen course 1: details of GET and POST requests, request headers
  • Day 15: React Hangman: Trigger fetch with click event callback vs useEffect
  • Day 16: REST API and CRUD
  • Day 17: Boring Book App part 1: React Frontend, Express Backend, GET requests, CORS
  • Day 18: Boring Book App part 2: POST request, File System API
  • Day 19: Boring Book App part 3: Request Parameters, DELETE request
  • Day 20: Boring Book App part 4: PUT request
  • Day 21: Express JS vs Vanilla JS part 1: Server setup, routes
  • Day 22: Express JS vs Vanilla JS part 2: Serve static files with Vanilla Server
  • Day 23: Express JS vs Vanilla JS part 3: Serve static files with Express Server, Middleware
  • Day 24: Express JS: express.Router, Postman
  • Day 25: Express JS: express-handlebars
  • Day 26: MongoDB: Installation, noSQL database structure, Mongo Shell commands
  • Day 27: MongoDB: Project setup, JSON vs BSON, connecting to database, inserting a record