The all-in-one guide for using Mongodb with Go

Akshit Sadana
ADGVIT
Published in
2 min readMar 16, 2021

--

Note: This article is not a particular code walkthrough or guide. It mostly highlights key-points about the source code that can be found here.

Introduction

The repository is a sand-box that illustrates the usage pattern of Mongodb in Go using the go-mongo. The code is structured in a way making it easily pluggable with clean/onion/hexagonal architecture. The purpose of creating this sand-box is

  • minimal dependency of business logic implementation on Mongodb and mongo-driver.
  • proper implementation of singleton client and its usage across the app.
  • solid unit testing of db queries in a concurrent environment.
  • easy migration of db layer if required.

Folder specs

  • .github — contains action workflows and repository assets.
  • config — manages application configuration and environment variables.
  • entity — contains entities of all logical constituents.
  • random — functions to generate random data like string, integers, etc.
  • repository/mongo — implementation of mongo client, CRUD ops on all entities, unit testing of all CRUD functions.

A note on update operation

If you have noticed, instead of updating specific fields, the updateOne() function takes the complete updated entity and replaces it against a given matching parameter.

This is useful as it

  • makes update operation consistent
  • independent of any kind of persistence implementation(Sql, NoSql, Message-Ques, Cache).
  • can handle updates on a large number of fields simultaneously.
  • compatible with event-driven architectures.

Using UUID instead of ObjectID

I have chosen to use UUID as slug instead of objectID as it is only native to Mongodb and adds lots of conversion and validation related code. Using UUID makes all this excess code disappear.

Testing on CI

Following github action lints the source code and run unit tests.

name: mongodb CI

on:
workflow_dispatch:

jobs:
ci:
name: CI
runs-on: ubuntu-latest

services:
mongodb:
image: mongo
env:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: rootpassword
ports:
- 27017:27017

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.15

- name: install dependencies
run: |
make install
go get golang.org/x/lint/golint

- name: Lint code
run: |
make lint

- name: Test code
run: |
make test

Running tests parallelly

t.Parallel()

the above snippet makes the enclosing test function in a separate go-routine.

--

--