Building a Go-Based Microservice for User Preference Management

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setup
  4. Building our Go-Based Microservice
  5. Conclusion

Introduction

In this tutorial, we will learn how to build a Go-based microservice for user preference management. A microservice architecture is a popular architectural style for developing large-scale applications by breaking them down into smaller, independently deployable services. We will use Go (also known as Golang) for building our microservice due to its performance, simplicity, and excellent support for building networked applications.

By the end of this tutorial, you will have a functional Go-based microservice that can store and retrieve user preferences from a database. We will cover topics such as setting up the development environment, handling HTTP requests, interacting with a PostgreSQL database, structuring our project, and applying best practices and design patterns.

Prerequisites

Before we begin, make sure you have the following prerequisites:

Setup

To start, let’s set up our development environment:

  1. Install Go by following the instructions provided in the official documentation.
  2. Install PostgreSQL by following the instructions provided in the official documentation.

  3. Install a Go package manager called “dep” by running the following command in your terminal:

     $ go get -u github.com/golang/dep/cmd/dep
    

    With our prerequisites in place, we can now move on to building our Go-based microservice.

Building our Go-Based Microservice

Step 1: Setting up the Project Structure

We will begin by setting up the project structure. Open your terminal and execute the following commands:

$ mkdir user-preference-microservice
$ cd user-preference-microservice

Next, initialize Go modules by running the following command:

$ go mod init github.com/your-username/user-preference-microservice

This command initializes Go modules for our project and creates a go.mod file to manage dependencies.

Step 2: Creating the Database Connection

In this step, we will establish a connection with our PostgreSQL database. Create a new file called database.go in the root directory of your project and add the following code:

package main

import (
	"database/sql"
	"log"

	_ "github.com/lib/pq"
)

const (
	host     = "localhost"
	port     = 5432
	user     = "your-username"
	password = "your-password"
	dbname   = "user_pref_db"
)

func initializeDB() (*sql.DB, error) {
	connStr := "postgres://"+user+":"+password+"@/"+dbname+"?sslmode=disable"
	db, err := sql.Open("postgres", connStr)
	if err != nil {
		return nil, err
	}

	err = db.Ping()
	if err != nil {
		return nil, err
	}

	log.Println("Connected to the database!")
	return db, nil
}

Make sure to replace "your-username" and "your-password" with your PostgreSQL username and password. Additionally, update the const variables with your PostgreSQL host, port, and database name.

Step 3: Handling HTTP Requests

Now, let’s create an endpoint to handle HTTP requests. Create a new file called handlers.go in the root directory and add the following code:

package main

import (
	"encoding/json"
	"log"
	"net/http"
)

type UserPreference struct {
	ID       int    `json:"id"`
	Username string `json:"username"`
	Preference string `json:"preference"`
}

func getUserPreference(w http.ResponseWriter, r *http.Request) {
	// Implement logic to retrieve a user's preference from the database
}

func saveUserPreference(w http.ResponseWriter, r *http.Request) {
	// Implement logic to save a user's preference to the database
}

In the code above, we define a UserPreference struct to represent a user’s preference. We also declare two handler functions: getUserPreference and saveUserPreference. We will implement the logic for these functions in the upcoming steps.

Step 4: Implementing Database Operations

Let’s create a file named repository.go in the root directory to handle database operations. Add the following code:

package main

import (
	"log"

	"github.com/jmoiron/sqlx"
)

type UserRepository struct {
	db *sqlx.DB
}

func NewUserRepository(db *sql.DB) *UserRepository {
	return &UserRepository{
		db: sqlx.NewDb(db, "postgres"),
	}
}

func (r *UserRepository) GetUserPreference(username string) (*UserPreference, error) {
	// Implement logic to retrieve a user's preference from the database
}

func (r *UserRepository) SaveUserPreference(pref *UserPreference) error {
	// Implement logic to save a user's preference to the database
}

Step 5: Implementing HTTP Handlers

Update the handlers.go file with the following code:

package main

import (
	"encoding/json"
	"log"
	"net/http"
)

type UserPreference struct {
	ID        int    `json:"id"`
	Username  string `json:"username"`
	Preference string `json:"preference"`
}

type UserHandler struct {
	repo *UserRepository
}

func NewUserHandler(repo *UserRepository) *UserHandler {
	return &UserHandler{
		repo: repo,
	}
}

func (h *UserHandler) GetUserPreference(w http.ResponseWriter, r *http.Request) {
	// Implement logic to retrieve a user's preference from the database
}

func (h *UserHandler) SaveUserPreference(w http.ResponseWriter, r *http.Request) {
	// Implement logic to save a user's preference to the database
}

Step 6: Wiring it All Together

Finally, we will create the main file main.go to wire everything together:

package main

import (
	"log"
	"net/http"
)

func main() {
	db, err := initializeDB()
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	repo := NewUserRepository(db)
	handler := NewUserHandler(repo)

	http.HandleFunc("/users/preference", handler.GetUserPreference)
	http.HandleFunc("/users/preference/save", handler.SaveUserPreference)

	log.Println("Server is running on http://localhost:8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Step 7: Testing the Microservice

To test our microservice, run the following command in your terminal:

$ go run main.go

Now you can make HTTP requests to retrieve and save user preferences:

  • To retrieve a user’s preference:
    GET http://localhost:8080/users/preference?username=johndoe
    
  • To save a user’s preference:
    POST http://localhost:8080/users/preference/save
    Body:
    {
      "username": "johndoe",
      "preference": "dark"
    }
    

Congratulations! You have successfully built a Go-based microservice for user preference management. You can extend this microservice by adding more endpoints, implementing authentication, or integrating with other services.

Conclusion

In this tutorial, we learned how to build a Go-based microservice for user preference management. We covered setting up the project structure, establishing a database connection, handling HTTP requests, implementing database operations, and wiring it all together. We also touched on best practices and design patterns to follow while building microservices.

Remember to continuously improve your microservice by adding error handling, logging, and unit tests. This will ensure the reliability and maintainability of your application.

Happy coding!