gin

package
v1.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 1, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

Gin HTTP Server Package

Gin web framework wrapper package for Go.

Features

  • Based on Gin: High-performance web framework
  • Easy routing: GET, POST, PUT, DELETE, PATCH, Any methods
  • Group routing: URL path grouping support
  • Middleware: Global and route-specific middleware
  • Graceful Shutdown: Timeout-based safe shutdown
  • Thread-safe: Concurrency safety guaranteed

Installation

go get github.com/common-library/go/http/gin
go get github.com/gin-gonic/gin

When to Choose Gin

  • ✅ Ultra-high performance API servers needed
  • ✅ REST APIs with heavy JSON processing
  • ✅ Preference for simple API structure
  • ✅ Fast development speed important
  • ✅ Active community support needed

Usage Examples

Basic Server
package main

import (
    "net/http"
    "github.com/common-library/go/http/gin"
    "github.com/gin-gonic/gin"
)

func main() {
    server := &gin.Server{}
    
    // Simple handler
    server.RegisterHandler(http.MethodGet, "/", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello, World!")
    })
    
    // JSON response
    server.RegisterHandler(http.MethodGet, "/api/hello", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Hello from Gin",
        })
    })
    
    // Start server
    err := server.Start(":8080", func(err error) {
        log.Fatalf("Server error: %v", err)
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Wait for shutdown
    select {}
}
Route Registration Methods
server := &gin.Server{}

// Basic registration
server.RegisterHandler(http.MethodGet, "/users", getUsersHandler)
server.RegisterHandler(http.MethodPost, "/users", createUserHandler)
server.RegisterHandler(http.MethodPut, "/users/:id", updateUserHandler)
server.RegisterHandler(http.MethodDelete, "/users/:id", deleteUserHandler)
server.RegisterHandler(http.MethodPatch, "/users/:id", patchUserHandler)

// Allow all methods
server.RegisterHandlerAny("/webhook", webhookHandler)

// Register with middleware
server.RegisterHandler(http.MethodGet, "/admin", adminHandler, authMiddleware, logMiddleware)
server.RegisterHandlerAny("/api/catch-all", catchAllHandler, authMiddleware)
Wrapping Standard HTTP Handlers
import (
    "net/http"
    "github.com/common-library/go/http/gin"
)

// Wrap http.Handler (e.g., http.FileServer)
fs := http.FileServer(http.Dir("./static"))
server.RegisterHandler(http.MethodGet, "/static/*filepath", gin.WrapHandler(fs))

// Wrap http.HandlerFunc - Method 1: Using WrapHandler
stdHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello from standard handler"))
})
server.RegisterHandler(http.MethodGet, "/std1", gin.WrapHandler(stdHandler))

// Wrap http.HandlerFunc - Method 2: Using WrapHandlerFunc (recommended)
handler := func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Hello World"))
}
server.RegisterHandler(http.MethodGet, "/std2", gin.WrapHandlerFunc(handler))

// Wrap third-party handlers
server.RegisterHandler(http.MethodGet, "/prometheus", gin.WrapHandler(promhttp.Handler()))
Group Routing
server := &gin.Server{}

// Create API group
api := server.Group("/api")

// Routes within group
api.GET("/users", func(c *gin.Context) {
    c.JSON(http.StatusOK, users)
})

api.POST("/users", func(c *gin.Context) {
    // Create user logic
    c.JSON(http.StatusCreated, newUser)
})

// Nested groups
v1 := api.Group("/v1")
v1.GET("/info", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{"version": "1.0"})
})

// Group-specific middleware
admin := api.Group("/admin", adminAuthMiddleware)
admin.GET("/stats", getStatsHandler)
Middleware Usage
import "github.com/gin-gonic/gin"

server := &gin.Server{}

// Global middleware
server.Use(gin.Logger())
server.Use(gin.Recovery())

// Custom middleware
authMiddleware := func(c *gin.Context) {
    token := c.GetHeader("Authorization")
    if token == "" {
        c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "missing token"})
        return
    }
    c.Next()
}

server.RegisterHandler(http.MethodGet, "/protected", protectedHandler, authMiddleware)

// CORS middleware
corsMiddleware := func(c *gin.Context) {
    c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
    c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
    c.Next()
}
server.Use(corsMiddleware)
Request Processing Examples
// Path parameters
server.RegisterHandler(http.MethodGet, "/users/:id", func(c *gin.Context) {
    id := c.Param("id")
    c.String(http.StatusOK, "User ID: "+id)
})

// Query parameters
server.RegisterHandler(http.MethodGet, "/search", func(c *gin.Context) {
    query := c.Query("q")
    page := c.DefaultQuery("page", "1")
    c.JSON(http.StatusOK, gin.H{
        "query": query,
        "page":  page,
    })
})

// JSON binding
type User struct {
    Name  string `json:"name" binding:"required"`
    Email string `json:"email" binding:"required,email"`
}

server.RegisterHandler(http.MethodPost, "/users", func(c *gin.Context) {
    var u User
    if err := c.ShouldBindJSON(&u); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    c.JSON(http.StatusCreated, u)
})

// Form data
server.RegisterHandler(http.MethodPost, "/form", func(c *gin.Context) {
    name := c.PostForm("name")
    email := c.DefaultPostForm("email", "default@example.com")
    c.JSON(http.StatusOK, gin.H{
        "name":  name,
        "email": email,
    })
})
Graceful Shutdown
import (
    "os"
    "os/signal"
    "syscall"
    "time"
)

server := &gin.Server{}
server.RegisterHandler(http.MethodGet, "/", homeHandler)

// Start server
server.Start(":8080", func(err error) {
    log.Printf("Server error: %v", err)
})

// Wait for signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

// Graceful shutdown (10 second timeout)
log.Println("Shutting down server...")
if err := server.Stop(10 * time.Second); err != nil {
    log.Fatal(err)
}
log.Println("Server stopped")
Direct Gin Engine Access
server := &gin.Server{}

// Get Gin engine
engine := server.GetEngine()

// Advanced settings
engine.MaxMultipartMemory = 8 << 20 // 8 MiB

// Serve static files
engine.Static("/static", "./public")
engine.StaticFile("/favicon.ico", "./resources/favicon.ico")

// HTML templates
engine.LoadHTMLGlob("templates/*")
engine.GET("/index", func(c *gin.Context) {
    c.HTML(http.StatusOK, "index.html", gin.H{
        "title": "Home",
    })
})

// File upload
engine.POST("/upload", func(c *gin.Context) {
    file, _ := c.FormFile("file")
    c.SaveUploadedFile(file, "./uploads/"+file.Filename)
    c.String(http.StatusOK, "Uploaded: "+file.Filename)
})
Server Status Check
server := &gin.Server{}

// Before starting server
if !server.IsRunning() {
    server.Start(":8080", nil)
}

// Prevent duplicate start
if server.IsRunning() {
    log.Println("Server already running")
    return
}

// Health check endpoint
server.RegisterHandler(http.MethodGet, "/health", func(c *gin.Context) {
    status := "down"
    if server.IsRunning() {
        status = "up"
    }
    c.JSON(http.StatusOK, gin.H{"status": status})
})

API Documentation

Server
RegisterHandler(method, path string, handler gin.HandlerFunc, middleware ...gin.HandlerFunc)

Registers an HTTP handler.

  • method: HTTP method (http.MethodGet, http.MethodPost, etc.)
  • path: URL path pattern
  • handler: Gin handler function
  • middleware: Optional middleware
RegisterHandlerAny(path string, handler gin.HandlerFunc, middleware ...gin.HandlerFunc)

Registers a handler for all HTTP methods.

  • path: URL path pattern
  • handler: Gin handler function
  • middleware: Optional middleware
WrapHandler(handler http.Handler) gin.HandlerFunc

Wraps a standard http.Handler into a Gin handler function.

  • handler: Standard http.Handler to wrap
  • return: Gin-compatible handler function

Use this for wrapping http.FileServer, third-party handlers, or any type implementing http.Handler.

WrapHandlerFunc(handlerFunc http.HandlerFunc) gin.HandlerFunc

Wraps a standard http.HandlerFunc into a Gin handler function.

  • handlerFunc: Standard http.HandlerFunc to wrap
  • return: Gin-compatible handler function

This is a convenience function for wrapping function types directly. Uses Gin's WrapF which is optimized for HandlerFunc types.

Use(middleware ...gin.HandlerFunc)

Registers global middleware.

Group(relativePath string, handlers ...gin.HandlerFunc) *gin.RouterGroup

Creates a router group.

  • relativePath: Group path prefix
  • handlers: Group middleware
  • return: Gin RouterGroup instance
Start(address string, listenAndServeFailureFunc func(err error)) error

Starts the server.

  • address: Server address (e.g., ":8080")
  • listenAndServeFailureFunc: Error callback (excludes http.ErrServerClosed)
Stop(shutdownTimeout time.Duration) error

Safely shuts down the server.

  • shutdownTimeout: Shutdown wait time
IsRunning() bool

Returns the server running status.

GetEngine() *gin.Engine

Provides direct access to the Gin engine.

Framework Comparison

Feature Gin Echo Gorilla Mux
Performance ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
Learning Curve Easy Easy Medium
Middleware Rich Rich Basic
Data Binding
Validation
JSON Performance Best Very Good Average
Community Very Active Active Active
GitHub Stars 78k+ 29k+ 20k+

Notes

  • Gin handlers have no return value (void)
  • Control middleware chain with c.Next() or c.Abort()
  • http.ErrServerClosed is considered normal shutdown and won't trigger the error callback
  • Cannot start multiple servers on the same port
  • For production environments, recommend setting gin.SetMode(gin.ReleaseMode)

References

License

This package follows the project's license.

Documentation

Overview

Package gin provides a simplified wrapper around the Gin web framework.

This package offers convenient methods for creating and managing Gin HTTP servers with support for routing, middleware, and graceful shutdown.

Features:

  • Simplified server setup with Gin
  • Handler and middleware registration
  • Group routing support
  • Graceful shutdown with timeout
  • Thread-safe operations

Example:

server := &gin.Server{}
server.RegisterHandler(http.MethodGet, "/hello", func(c *gin.Context) {
    c.String(200, "Hello, World!")
})
server.Start(":8080", nil)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WrapHandler

func WrapHandler(handler http.Handler) gin.HandlerFunc

WrapHandler wraps a standard http.Handler into a Gin handler function.

This function allows you to use standard Go http.Handler implementations (such as http.FileServer, third-party handlers, or http.HandlerFunc) within the Gin framework.

Parameters:

  • handler: Standard http.Handler to wrap

Returns:

  • gin.HandlerFunc: Gin-compatible handler function

Example:

// Wrap http.FileServer
fs := http.FileServer(http.Dir("./static"))
server.RegisterHandler(http.MethodGet, "/static/*filepath", WrapHandler(fs))

// Wrap http.HandlerFunc
stdHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello from standard handler"))
})
server.RegisterHandler(http.MethodGet, "/std", WrapHandler(stdHandler))

func WrapHandlerFunc

func WrapHandlerFunc(handlerFunc http.HandlerFunc) gin.HandlerFunc

WrapHandlerFunc wraps a standard http.HandlerFunc into a Gin handler function.

This is a convenience function that wraps http.HandlerFunc (a function type) into a Gin-compatible handler. It uses Gin's WrapF function which is optimized for HandlerFunc types.

Parameters:

  • handlerFunc: Standard http.HandlerFunc to wrap

Returns:

  • gin.HandlerFunc: Gin-compatible handler function

Example:

// Wrap a HandlerFunc directly
handler := func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Hello World"))
}
server.RegisterHandler(http.MethodGet, "/hello", WrapHandlerFunc(handler))

// Or use with http.HandlerFunc type conversion
server.RegisterHandler(http.MethodPost, "/api", WrapHandlerFunc(
    http.HandlerFunc(myStandardHandler),
))

Types

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a struct that provides Gin HTTP server related methods.

func (*Server) GetEngine

func (s *Server) GetEngine() *gin.Engine

GetEngine returns the underlying Gin engine for advanced usage.

Returns:

  • *gin.Engine: Gin engine instance

Use this method when you need direct access to Gin's API for advanced configuration.

Example:

engine := server.GetEngine()
engine.SetTrustedProxies([]string{"127.0.0.1"})

func (*Server) Group

func (s *Server) Group(relativePath string, handlers ...gin.HandlerFunc) *gin.RouterGroup

Group creates a new router group.

Parameters:

  • relativePath: Path prefix for the group
  • handlers: Optional middleware for the group

Returns:

  • *gin.RouterGroup: Gin router group

Example:

api := server.Group("/api/v1")
api.GET("/users", getUsersHandler)

func (*Server) IsRunning

func (s *Server) IsRunning() bool

IsRunning returns whether the server is currently running.

Returns:

  • bool: true if server is running, false otherwise

Example:

if server.IsRunning() {
    fmt.Println("Server is active")
}

func (*Server) RegisterHandler

func (s *Server) RegisterHandler(method, relativePath string, handlers ...gin.HandlerFunc)

RegisterHandler registers an HTTP handler with optional middleware.

Parameters:

  • method: HTTP method (http.MethodGet, http.MethodPost, etc.)
  • relativePath: URL path pattern
  • handlers: Gin handler functions (handler + optional middleware)

Example:

server.RegisterHandler(http.MethodGet, "/users/:id", getUserHandler)

func (*Server) RegisterHandlerAny

func (s *Server) RegisterHandlerAny(relativePath string, handlers ...gin.HandlerFunc)

RegisterHandlerAny registers handlers for all HTTP methods.

Parameters:

  • relativePath: URL path pattern
  • handlers: Gin handler functions

Example:

server.RegisterHandlerAny("/ping", pingHandler)

func (*Server) Start

func (s *Server) Start(address string, listenAndServeFailureFunc func(err error)) error

Start starts the Gin HTTP server.

Parameters:

  • address: Server address (e.g., ":8080", "localhost:3000")
  • listenAndServeFailureFunc: Optional callback for server errors (excluding graceful shutdown)

Returns:

  • error: Error if server is already running or fails to start

The server runs in a background goroutine. Use Stop() for graceful shutdown.

Example:

err := server.Start(":8080", func(err error) {
    log.Printf("Server error: %v", err)
})

func (*Server) Stop

func (s *Server) Stop(shutdownTimeout time.Duration) error

Stop gracefully shuts down the Gin server.

Parameters:

  • shutdownTimeout: Maximum time to wait for shutdown

Returns:

  • error: Error if shutdown fails

Example:

err := server.Stop(10 * time.Second)

func (*Server) Use

func (s *Server) Use(middleware ...gin.HandlerFunc)

Use registers global middleware.

Parameters:

  • middleware: Middleware functions to apply globally

Example:

server.Use(gin.Logger(), gin.Recovery())

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL