Integrating Official Mongo-Driver to Revel Web Framework

Umayanga Gunawardhana
3 min readJun 23, 2022

--

https://www.techunits.com/topics/tutorials/golang-web-application-with-revel/

Introduction

If you are working with Golang and MongoDB, you will be able to find a lot of content on the internet to guide you on how to work with these two. However, if you are using the Revel Web Framework, you might find it a bit tricky, when it comes to integrating the official go.mongodb.org/mongo-driver into your Revel-based web application. Moreover, I hardly found any up-to-date content to help me with it, except the official documentation, which doesn’t explain Revel integration. Therefore, I thought I would write down how to integrate the official mongo-driver into your Revel web application.

Setting up the Project

First, you need to create a Revel project. If you are unfamiliar with setting up a Revel project, please refer to https://revel.github.io/tutorial/gettingstarted.html.

Create the MongoDB Service

Once you have the project set up, let's move on to setting up the database service.

First, create the file in your project_name/app/mongo_driver/service.go directory. Then copy the following code into it. This will define the MongoDB service.

package mongo_driver

import (
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
)

type MongoOfficialDatabaseService struct {
client *mongo.Client
path string
dbName string
maxPool int
}

func (s *MongoOfficialDatabaseService) new(path string, name string, maxPool int) error {
var err error
s.path, s.dbName, s.maxPool = path, name, maxPool
log.Println("creating new mongodb client...")
client, err := mongo.NewClient(options.Client().ApplyURI(service.path).SetMaxPoolSize(uint64(service.maxPool)))
if err != nil {
log.Fatal(err)
}

err = client.Connect(Context)
if err != nil {
return err
}
err = client.Ping(Context, nil)
if err != nil {
return err
}
log.Println("connected to mongodb successfully")
service.client = client
return nil
}

Then in the same directory, create, project_name/app/mongo_driver/handler.go file and add the following code to create the handler class.

package mongo_driver

import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"log"
"os"
)

var service MongoOfficialDatabaseService
var Context = context.TODO()

func InitConnection(path string, dbName string, maxPool int) {
if service.client == nil {

err := service.new(path, dbName, maxPool)
if err != nil {
log.Println("error connecting to MongoDB database server:", service.path)
os.Exit(1)
}
}
}

func GetCollection(name string) *mongo.Collection {
return service.client.Database(service.dbName).Collection(name)
}

func DisconnectService() {
err := service.client.Disconnect(Context)
if err != nil {
log.Fatal("error disconnecting Mongo Client")
}
}

Add Configuration

Now in the project_name/conf/app.conf file add the following database configurations under [dev] and [prod] sections.

[dev]
...
mongo.database = test_db
mongo.path = mongodb://user:password@127.0.0.1:27017/test_db
mongo.maxPool = 20
....

Replace test_db, user, and password with the database name, username and password for your MongoDB database.

Next, we need to load these config parameters and initialize the database service. For that, we will write a loader file in project_name/app/mongo_driver/loader.go

package mongo_driverimport (   
"log"
"github.com/revel/revel"
)
func LoadDatabaseHandler() {
// load database config - please note the errors are not handled
dbName, _ := revel.Config.String("mongo.database")
path, _ := revel.Config.String("mongo.path")
maxPool = revel.Config.IntDefault("mongo.maxPool", 20)

// initialize database service
InitConnection(path, dbName, maxPool)
}

Load Service on App Start

The next step is to configure the Revel app to start the database on application start. For that, we will use the OnAppStart hook in Revel. To set it up, go to project_name/app/init.go file and add the following lines under the init() function.

func init()...
Config, err := config.LoadContext("app.conf", revel.CodePaths)
if err != nil || Config == nil {
log.Fatalf("%+v", err)
}
...
// Load database handler
revel.OnAppStart(mongo_driver.LoadDatabaseHandler) // add this line
// Graceful Shutdown - disconnect database client on app stop
revel.OnAppStop(mongo_driver.DisconnectService) // add this line too

The OnAppStop hook executes when the Revel server is stopping and takes care of closing the client connection with the database.

Now the driver integration is complete and you may run the Revel application using the revel run command.

Example

Let us see how to perform a simple insert operation with our service. First, retrieve the collection from the database.

samplesCollection := mongo_driver.GetCollection("sample_collection")_, err := samplesCollection.InsertOne(mongo_driver.Context, sample)
if err != nil {
log.Println("error inserting to collection: ", err)
}

For more details on examples of performing CRUD operations, and managing sessions and transactions, please refer to official mongo-driver documentation. The documentation will help you code everything from this point onwards.

References

  1. https://www.mongodb.com/docs/drivers/go/current/
  2. https://pkg.go.dev/go.mongodb.org/mongo-driver?utm_source=godoc
  3. https://revel.github.io/

--

--