First Cache Mechanism Golang With Redis
Jun 7, 2019
2 minute read

package main

import (
	"database/sql"
	"github.com/go-redis/redis"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
	"log"
	"net/http"
    "time"
    "os"
)

type DB struct {
	redis *redis.Client
	mysql *sql.DB
}

func NewDB() *DB {
	opt := &redis.Options{
		Addr: os.Getenv("REDIS_HOST"),
		Password: "", 
		DB:       0, 
	}

	client := redis.NewClient(opt)
	pong, err := client.Ping().Result()
	if err != nil {
		log.Panic(err, pong)
	}

	db, err := sql.Open(os.Getenv("DB_DRIVER"), os.Getenv("DB_DSN"))
	if err != nil {
		log.Panic(err)
	}


	return &DB{redis: client, mysql: db}
}

func (d *DB) Fetch(w http.ResponseWriter, r *http.Request) {
    keyID := mux.Vars[r]["id"]
	val, err := d.redis.Get(keyID).Result()
	if err != nil {
        // Do Logical Here to Select data From Database
        // And Set the Value from Database to Redis
        // Set Expiration to 5 second
		err := d.redis.Set(keyID, "Hello From Redis", 5 * time.Second).Err()
		if err != nil {
			log.Panic(err)
		}

        // Send The Headers and Payload
		w.Header().Add("X-Cache", "MISS")
		w.WriteHeader(200)
		w.Write([]byte("Fetch from Database"))
		return
	}

    // Send The Headers and Payload value From Redis Cache
	w.Header().Add("X-Cache", "HIT")
	w.WriteHeader(200)
	w.Write([]byte(val))
	return
}

func main() {
	db := NewDB()
	r := mux.NewRouter()
	r.HandleFunc("/{id}", db.Fetch)
	http.ListenAndServe(":81", r)
}

Testing with httpie


http GET http://localhost:81/redis_key

// First payload because cache not exist
HTTP/1.1 200 OK
Content-Length: 18
Content-Type: text/plain; charset=utf-8
Date: Fri, 07 Jun 2019 09:28:04 GMT
X-Cache: MISS

http GET http://localhost:81/redis_key

// Second payload, fetch data from redis cache
HTTP/1.1 200 OK
Content-Length: 18
Content-Type: text/plain; charset=utf-8
Date: Fri, 07 Jun 2019 09:28:04 GMT
X-Cache: HIT