{
  "slug": "Golang-Gin-Middleware-and-Health-Controller-fe53ce9d9754",
  "title": "Golang Gin Middleware and Health Controller",
  "subtitle": "In the previous article, a simple Golang project was demonstrated. In our current work, it is necessary to add a Gin middleware to handle…",
  "excerpt": "In the previous article, a simple Golang project was demonstrated. In our current work, it is necessary to add a Gin middleware to handle…",
  "date": "2025-08-10",
  "tags": [
    "Go"
  ],
  "readingTime": "3 min",
  "url": "https://medium.com/@mobinshaterian/golang-gin-middleware-and-health-controller-fe53ce9d9754",
  "hero": "https://cdn-images-1.medium.com/max/800/1*Zk4CkFWRdf7HpNA-iNjn7w.jpeg",
  "content": [
    {
      "type": "paragraph",
      "html": "In the previous article, a simple Golang project was demonstrated. In our current work, it is necessary to add a Gin middleware to handle requests with a timeout limit of more than 60 seconds."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*Zk4CkFWRdf7HpNA-iNjn7w.jpeg",
      "alt": "Golang Gin Middleware and Health Controller",
      "caption": "",
      "width": 1024,
      "height": 1024
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Health Controller"
    },
    {
      "type": "paragraph",
      "html": "In a microservice architecture, a health controller is commonly implemented as a simple endpoint that returns an ‘OK’ response to indicate that the service is functioning correctly. This mechanism is widely used to monitor the status of individual services, ensuring system reliability. By providing real-time feedback, such endpoints help developers identify and address issues promptly."
    },
    {
      "type": "paragraph",
      "html": "Router.go"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "package appfunc (a *Application) Routes() {\n    api := a.Router.Group(\"/api/v1/\") api.GET(\"/health\", HealthHandler)\n}"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "package app\nimport (\n\"net/http\"\n\"time\"\n\"github.com/gin-gonic/gin\"\n)\nfunc HealthHandler(c *gin.Context) {\n    c.JSON(http.StatusOK, gin.H{\n        \"message\": \"OK\",\n    })\n}"
    },
    {
      "type": "paragraph",
      "html": "test.go"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "package test\nimport (\n\"encoding/json\"\n\"io\"\n\"net/http\"\n\"testing\"\n\"time\" application \"go-simple/cmd/web/app\"\n)\nfunc startTestServer() {\n    a := application.New() a.Routes() a.StartServer() time.Sleep(200 * time.Millisecond) // Give\n    server time to start\n}\nfunc TestHealthEndpoint(t *testing.T) {\n    t.Parallel() startTestServer() resp, err := http.Get(\"http://localhost:4000/api/v1/health\") if\n    err != nil {\n        t.Fatalf(\"Failed to send GET request: %v\", err)\n    }\n    defer resp.Body.Close() if resp.StatusCode != http.StatusOK {\n        t.Errorf(\"Expected status 200 OK, got %d\", resp.StatusCode)\n    }\n    body, err := io.ReadAll(resp.Body) if err != nil {\n        t.Fatalf(\"Failed to read response body: %v\", err)\n    }\n    // Parse JSON\n    var data map[string]string err = json.Unmarshal(body, &data) if err != nil {\n        t.Fatalf(\"Expected JSON response, got error: %v\", err)\n    }\n    // Validate the message message, ok := data[\"message\"] if !ok {\n        t.Fatalf(\"Missing 'message' field in response: %v\", data)\n    }\n    if message != \"OK\" {\n        t.Errorf(\"Expected message 'hello world', got '%s'\", message)\n    }\n}"
    },
    {
      "type": "embed",
      "provider": "youtube",
      "url": "https://www.youtube.com/embed/gbTIh3lNtVs?feature=oembed"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "TimeOut Middleware"
    },
    {
      "type": "paragraph",
      "html": "One common technique used by hackers involves sending high-volume processing requests to overwhelm a system. To mitigate this, it is essential to terminate connections after 60 seconds. The Gin framework effectively addresses this issue by implementing middleware that automatically manages and closes such connections, enhancing system security."
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (a *Application) Routes() {\n    api := a.Router.Group(\"/api/v1/\") api.GET(\"/slow\", SlowHandler)\n}"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func SlowHandler(c *gin.Context) {\n    // Simulate a slow response time.Sleep(70 * time.Second) c.JSON(http.StatusOK, gin.H{\n        \"message\": \"This is a slow response\",\n    })\n}"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func New() *Application {\n    // Set release mode gin.SetMode(gin.DebugMode) // Use New() for full control, or Default() if\n    you're okay with built-ins router := gin.New() // Add middleware explicitly router.Use(gin.Logger()) router.Use(gin.Recovery()) router.Use(timeout.New(timeout.WithTimeout(60 * time.Second))) // timeout middleware port := os.Getenv(\"PORT\") if port == \"\" {  port = defaultPort } return &Application{Port: port, Router: router}}"
    },
    {
      "type": "paragraph",
      "html": "test.go"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func startTestServer() {\n    a := application.New() a.Routes() a.StartServer() time.Sleep(200 * time.Millisecond) // Give\n    server time to start\n}"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func TestSlowEndpoint(t *testing.T) {\n    t.Parallel() startTestServer() resp, err := http.Get(\"http://localhost:4000/api/v1/slow\") if err\n    != nil {\n        t.Fatalf(\"Failed to send GET request: %v\", err)\n    }\n    defer resp.Body.Close() if resp.StatusCode != http.StatusRequestTimeout {\n        t.Errorf(\"Expected status 408 OK, got %d\", resp.StatusCode)\n    }\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "GitHub codes"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Conclusion"
    },
    {
      "type": "paragraph",
      "html": "In this article, we explored the implementation of a Golang HTTP server using the Gin framework, focusing on the integration of a health controller and timeout middleware to enhance system reliability and security. The health controller, implemented as a simple /api/v1/health endpoint, returns an “OK” response to confirm the service’s operational status, a critical feature for monitoring in microservice architectures. The accompanying test ensures the endpoint functions correctly by validating the response status and JSON payload. Additionally, we introduced a timeout middleware to mitigate potential denial-of-service attacks by terminating requests exceeding 60 seconds, as demonstrated with the /api/v1/slow endpoint. The middleware, combined with robust testing, ensures the server handles prolonged requests appropriately by returning a 408 Request Timeout status. Together, these components — health checks and timeout handling — provide a solid foundation for building secure and reliable Golang applications. The complete code, including these features, is available in the GitHub repository, offering a practical reference for developers aiming to implement similar functionality."
    }
  ]
}
