First Cache Mechanism Golang With Redis
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