-
Notifications
You must be signed in to change notification settings - Fork 51
2. Using Redis DB: key value
Mahir edited this page Jul 23, 2022
·
4 revisions
Important: Make sure Redis server is installed on the machine.
Endpoints:
Add a new country: [HTTP POST] http://localhost:1200/api/v1/new-country
Body:
{
"countryName":"",
"countryUNcode":""
}
Find a country: [HTTP GET] http://localhost:1200/api/v1/search-country/:countryName
This is a continuation of 1. RESTful API: Hello world project.
- Create a file
countries.go
insidecontroller
folder - Write a function
AddCountry
tocountries.go
file - Write a function
FindCountry
tocountries.go
file
package controller
import (
"context"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/mediocregopher/radix/v4"
"github.com/pilinux/gorest/database"
"github.com/pilinux/gorest/lib/renderer"
)
// CountryCode - key:value
type CountryCode struct {
CountryName string `json:"countryName"`
CountryUNcode string `json:"countryUNcode"`
}
// AddCountry - SET key
func AddCountry(c *gin.Context) {
data := CountryCode{}
if err := c.ShouldBindJSON(&data); err != nil {
renderer.Render(c, gin.H{"msg": "bad request"}, http.StatusBadRequest)
return
}
data.CountryName = strings.TrimSpace(data.CountryName)
data.CountryUNcode = strings.TrimSpace(data.CountryUNcode)
if len(data.CountryName) < 4 {
renderer.Render(c, gin.H{"msg": "requires a valid country name"}, http.StatusBadRequest)
return
}
if len(data.CountryUNcode) < 3 {
renderer.Render(c, gin.H{"msg": "requires a valid country UN code (3-digit)"}, http.StatusBadRequest)
return
}
client := database.GetRedis()
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(database.RedisConnTTL)*time.Second)
defer cancel()
// Set key in Redis
result := ""
if err := client.Do(ctx, radix.FlatCmd(&result, "SET", data.CountryName, data.CountryUNcode)); err != nil {
renderer.Render(c, gin.H{"msg": "internal server error"}, http.StatusInternalServerError)
return
}
if result != "OK" {
renderer.Render(c, gin.H{"msg": "operation failed"}, http.StatusNotAcceptable)
return
}
renderer.Render(c, data, http.StatusOK)
}
// FindCountry - GET key
func FindCountry(c *gin.Context) {
countryName := c.Params.ByName("country-name")
countryName = strings.TrimSpace(countryName)
if len(countryName) < 4 {
renderer.Render(c, gin.H{"msg": "requires a valid country name"}, http.StatusNotFound)
return
}
data := CountryCode{}
data.CountryName = countryName
client := database.GetRedis()
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(database.RedisConnTTL)*time.Second)
defer cancel()
// Is key available in Redis
result := 0
if err := client.Do(ctx, radix.FlatCmd(&result, "EXISTS", data.CountryName)); err != nil {
renderer.Render(c, gin.H{"msg": "internal server error"}, http.StatusInternalServerError)
return
}
if result == 0 {
renderer.Render(c, gin.H{"msg": "country does not exist in the database"}, http.StatusNotFound)
return
}
// Find key in Redis
if err := client.Do(ctx, radix.FlatCmd(&data.CountryUNcode, "GET", data.CountryName)); err != nil {
renderer.Render(c, gin.H{"msg": "internal server error"}, http.StatusInternalServerError)
return
}
renderer.Render(c, data, http.StatusOK)
}
- Update the
main
function inmain.go
file
package main
import (
"fmt"
"myapi/controller"
"github.com/gin-gonic/gin"
"github.com/pilinux/gorest/config"
"github.com/pilinux/gorest/database"
"github.com/pilinux/gorest/lib/middleware"
)
var configure = config.Config()
func main() {
if configure.Database.REDIS.Activate == "yes" {
// Initialize REDIS client
if _, err := database.InitRedis(); err != nil {
fmt.Println(err)
return
}
}
router, err := SetupRouter()
if err != nil {
fmt.Println(err)
return
}
err = router.Run(":" + configure.Server.ServerPort)
if err != nil {
fmt.Println(err)
return
}
}
// SetupRouter ...
func SetupRouter() (*gin.Engine, error) {
router := gin.Default()
router.Use(middleware.CORS(
configure.Security.CORS.Origin,
configure.Security.CORS.Credentials,
configure.Security.CORS.Headers,
configure.Security.CORS.Methods,
configure.Security.CORS.MaxAge,
))
// For gorest <= v1.4.5
// router.Use(middleware.CORS())
// API:v1
v1 := router.Group("/api/v1/")
{
v1.GET("greetings", controller.Greetings)
if configure.Database.REDIS.Activate == "yes" {
v1.POST("new-country", controller.AddCountry)
v1.GET("search-country/:country-name", controller.FindCountry)
}
}
return router, nil
}
- Rename the file from
.env.sample
to.env
and modify the following lines:
APP_PORT=1200
ACTIVATE_REDIS=yes
- Build and start the app
go mod tidy -compat=1.17
go build
chmod +x myapi
./myapi
myapi
│--- main.go
│--- go.mod
│--- go.sum
│--- .env
│
└─── controller
│ └--- greetings.go
│ └--- countries.go