Gin
Main
To initialize the server when run on specific port
package main
import (
"golang-playground/controller"
"log"
"os"
"os/signal"
"syscall"
"github.com/joho/godotenv"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Println("Error loading .env file")
}
controller := controller.NewInternalController()
// open the new thread to run the server instead of blocking the main thread
go func() {
if err := controller.Run("8080"); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
}Controller
To declare each api end point and applied middleware
package controller
import (
"golang-playground/middleware"
"golang-playground/service"
"time"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
type InternalController struct {
router *gin.Engine
}
type TestBody struct {
// name can be nullable, if not provided, the default value is empty string
Name *string `json:"name"`
Action string `json:"action" binding:"required"`
}
func NewInternalController() *InternalController {
r := gin.Default()
corsConfig := cors.DefaultConfig()
r.SetTrustedProxies([]string{"127.0.0.1", "::1"})
corsConfig.AllowOrigins = []string{"http://localhost:5000", "http://localhost:5006"}
// Configure CORS
corsConfig.AllowMethods = []string{"POST", "GET", "PUT", "OPTIONS"}
corsConfig.AllowHeaders = []string{"Origin", "Content-Type", "Authorization", "X-CSRF-Token"}
corsConfig.ExposeHeaders = []string{"Content-Length", "X-CSRF-Token"}
corsConfig.AllowCredentials = true
corsConfig.MaxAge = 12 * time.Hour
// apply cors as middleware
r.Use(cors.New(corsConfig))
internalService := service.NewInternalService()
internalMiddleware := middleware.NewInternalMiddleware()
// separate the routes
app := r.Group("/app")
// apply internal middleware
app.Use(internalMiddleware.SubscriptionKeyMiddleware())
{
app.GET("/items", func(c *gin.Context) {
items := internalService.GetItems()
c.JSON(200, items)
})
}
r.GET("/test/:name", func(c *gin.Context) {
name := c.Param("name")
action := c.Query("action")
c.JSON(200, gin.H{
"name": name,
"action": action,
})
})
r.POST("/test", func(c *gin.Context) {
var testBody TestBody
// body json validation
if err := c.ShouldBindJSON(&testBody); err != nil {
c.JSON(400, gin.H{
"error": err.Error(),
})
return
}
c.JSON(200, testBody)
})
return &InternalController{
router: r,
}
}
func (s *InternalController) Run(port string) error {
return s.router.Run(":" + port)
}
Middleware
To declare the middleware to intercept the request before passing to the controller
package middleware
import "github.com/gin-gonic/gin"
type InternalMiddleWare struct {
}
func NewInternalMiddleware() *InternalMiddleWare {
return &InternalMiddleWare{}
}
// Middleware to check for x-esi-accesskey header
func (m *InternalMiddleWare) SubscriptionKeyMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
subscriptionKey := c.GetHeader("x-esi-accesskey")
if subscriptionKey == "" {
c.AbortWithStatus(403)
return
}
c.Next()
}
}
Service
The logicial layer
package service
type InternalService struct {
}
func NewInternalService() *InternalService {
return &InternalService{}
}
func (s *InternalService) GetItems() [2]string {
return [2]string{"Item 1", "Item 2"}
}
Last updated
Was this helpful?