CRUD with MongoDB and Go - part #2

Author: Carmelo C.
Published: Oct 29, 2024
mongodb go golang crud docker containers

In part #1 we’ve done a lot of manual interaction with MongoDB. Scratching the surface is easy but there’s a lot under the hood. As always, remember to read the manual.

This article is shorter but it wraps up everything that’s been done in the previous one in a declarative fashion.

Let’s go…


First off, we create a directory where the initialization files will be stored:

$ mkdir -p init-mongodb/data

Next, create a file named init-mongodb/01-create-user-db.js which will store the procedure to login as root and create a new user:

try {
  print("Creating user...");

  // Create user
  db = db.getSiblingDB("admin");

  db.createUser({
    user: "dbuser",
    pwd: "pass123",
    roles: [{ role: "userAdminAnyDatabase", db: "admin" },
            { role: "readWrite", db: "Movies" } ],
    mechanisms: ["SCRAM-SHA-1"],
  });

  // Authenticate user
  db.auth({
    user: "dbuser",
    pwd: "pass123",
    mechanisms: ["SCRAM-SHA-1"]
  });

  // Create DB and collection
  db = new Mongo().getDB("Movies");
  db.createCollection("moviesList", { capped: false });
} catch (error) {
  print(`Failed to create DB user:\n${error}`);
}

NOTE: some syntax quirks aside, the contents reproduce the steps we’ve already tested.

The next two files are responsible for the initial insertion of test documents. file init-mongodb/02-init.sh:

#!/usr/bin/env bash
echo "########### Loading data to Mongo DB ###########"
mongoimport --jsonArray --db=Movies --collection=moviesList --file=/tmp/data/data.json

file init-mongodb/data/data.json:

[
  {"title": "Dune", "year": 1984, "director": "David Lynch"},
  {"title": "Avatar", "year": 9999, "director": "James Cameron"},
  {"title": "The Hobbit", "year": 2012, "director": "Peter Jackson"},
  {"title": "Arrival", "year": 2016, "director": "Denis Villeneuve"},
  {"title": "B Movie", "year": 1234, "director": "Unknown Person"}
]

Finally, docker-compose.yaml is to be modified to properly trigger MongoDB init scripts:

services:
  mongodb:
    image: mongo:8
    container_name: mongodb
    hostname: mongodb
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db
      - ./init-mongodb:/docker-entrypoint-initdb.d:ro    <<< init scripts
      - ./init-mongodb/data:/tmp/data:ro                 <<< init scripts
    networks:
      - backend
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

volumes:
  mongodb_data:
    name: mongodb_data

networks:
  backend:
    name: backend

Aaand, we’re done:

$ docker compose up -d

EXERCISE:

  1. start a second container (mongoclient)
  2. connect to the DB with mongosh
  3. authenticate with the ordinary user
  4. hack