- read

#2 Fullstack Micro frontends with angular & Golang

Venkata Krishna Bharadwaz Kopalle 3

Build full-stack micro frontends on angular & Golang-MongoDB with docker

This is Part 2 of my Full stack micro frontend series with angular & golang.
We will setup the backend services using Golang on Gin Framework.

Github Link. If you havent read other posts in this series, please go here.

As prerequisites, please make sure to Install Golang's latest version and read their awesomely curated case studies.

The official docs have a quick tutorial to get started with the GIN framework. Let’s deep dive into the setup and configurations.

Creating a module

Building the project with a module helps us to easily manage all the dependencies.

Go to the project directory, and run the command to initialize the module

go mod init <module-name>

this creates a new file go.mod

Install the GIN web framework

go get -u github.com/gin-gonic/gin

Bootstrapping

Create the main file main.go , add the following code

package mainimport (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {router := gin.Default()
router.Run("localhost:6000")
}

Install MongoDB

To download MongoDB

go get -u go.mongodb.org/mongo-driver/mongo

Additionally, download the dotenv where we set the MongoURI and the validator package for structs.

go get -u github.com/joho/godotenv github.com/go-playground/validator/v10

Note: Downloading above would install other supporting packages and updates the go.mod and generates a new file with go.sum

go. mod file
go.sum file

MongoDB Atlas

Mongo provides a cloud solution for your databases, you can choose the cloud provider. They have a free tier solution that remains free forever. Follow the steps from the official docs to set up your project on Atlas

Create Project files

Incorporating best practices at the start of the project would make it easy to maintain and manage

.env

create the env file for project-related URLs & secrets. For now let’s add the atlas URL, which can be obtained with the “Connect your application” option. Choose to go with +v1.6

MONGOURI=mongodb+srv://<username>:<password>@<AtlasClusterUrl>/?retryWrites=true&w=majority

Configurations

  • To fetch the mongo URI, we can create a function in a file env.go
  • To set up DB connections, let’s create another file setup.go

Models

We need to create a struct based on each mongo collection.

package models import "go.mongodb.org/mongo-driver/bson/primitive" type Project struct { 
Id primitive.ObjectID `json:"id,omitempty"`
Name string `json:"name,omitempty" validate:"required"`
members int `json:"members,omitempty" validate:"required"`
manager string `json:"manager,omitempty" validate:"required"`
}

Controllers

Controllers are responsible for handling the API requests. We will create a base controller with all the HTTP verbs.

package controllers // standard// add imports
import (
"context"
"mfe-golang-web-api/configs"
"mfe-golang-web-api/models"
"net/http"
"time"

"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)

let’s get the collections for CRUD operations. in our case, we are using projects collection for examples

var ProjectsCollection *mongo.Collection = configs.GetCollection(configs.DB, "projects")
var validate = validator.New()

POST to create a new project

func Create() gin.HandlerFunc { return func(c *gin.Context) { var project models.ProjectnewProject := models.Project{
Id: primitive.NewObjectID(),
Name: project.Name,
members: project.Project,
manager: project.Manager,
}

result, err := projectCollection.InsertOne(ctx, newProject)
//validate the request body
if result is successful, we then return a success response,
else we use the http library to handle the errors
}}

GET by projects by id and all the projects

func GetById() gin.HandlerFunc {return func(c *gin.Context) {

projectId := c.Param("projectId")
var project models.ProjectobjId, _ := primitive.ObjectIDFromHex(projectId)

err := projectCollection.FindOne(
ctx,
bson.M{"id": objId}
).Decode(&project)
if result is successful, we then return a success response,
else we use the http library to handle the errors
}}func GetAll() gin.HandlerFunc { return func(c *gin.Context) {

var projects []models.Project

results, err := projectCollection.Find(ctx, bson.M{})
if result is successful, we then return a success response,
else we use the http library to handle the errors
}}

PUT to update project by id

func Update() gin.HandlerFunc {

return func(c *gin.Context) {
projectId := c.Param("projectId")
var project models.Project
objId, _ := primitive.ObjectIDFromHex(projectId)

update := bson.M{
"name": project.Name,
"members": project.Members,
"manager": project.Manager
}

result, err := projectCollection.UpdateOne(
ctx,
bson.M{ "id": objId }, bson.M{"$set": update}
)

var updatedProject models.Project
if result.MatchedCount == 1 {
err := projectCollection.FindOne(
ctx,
bson.M{"id": objId}
).Decode(&updatedProject)
}

if result is successful, we then fetch the updated project and
return a success response,
else we use the http library to handle the errors
}

}

DELETE project by id

func Delete() gin.HandlerFunc { return func(c *gin.Context) {

projectId := c.Param("projectId")
objId, _ := primitive.ObjectIDFromHex(projectId)

result, err := projectCollection.DeleteOne(
ctx,
bson.M{"id": objId}
)
if result is successful, we then fetch the updated project and
return a success response,
else we use the http library to handle the errors

}
}

Routes

package routes import ( 
"mfe-golang-web-api/controllers"
"github.com/gin-gonic/gin"
)
func ProjectRoutes(router *gin.Engine) {
router.POST("/project", controllers.Create())
router.GET("/project/:projectId", controllers.GetById())
router.PUT("/project/:projectId", controllers.Update())
router.DELETE("/project/:projectId", controllers.Delete())
router.GET("/projects", controllers.GetAll())
}

Add the project routes to your main.go file

// inside the main function routes.ProjectRoutes(router)
router.Run("localhost:6000")

Run the Application

go run main.go

open your postman and add the API endpoints we just created for testing & debugging.

This marks the end of part 2 of this series, in the next part, we will discuss building the real applications on both the front end and the supporting APIs.

See ya later.