Sling Academy
Home/Golang/Using Middleware to Extend Go HTTP Servers

Using Middleware to Extend Go HTTP Servers

Last updated: November 27, 2024

In this article, we will explore how to enhance Go HTTP servers by utilizing middleware. Middleware functions in a Go server behave like chains, where each request passes through each middleware in the order it is set up, allowing applications to handle tasks such as authentication, logging, and more efficiently.

Understanding Middleware

Middleware in an HTTP server context can be considered interceptors, handling requests and potentially altering response behaviors before passing them on. Common use cases include authorization checks, input validation, and request logging.

Implementing Middleware in Go

To demonstrate middleware in Go, we'll create a simple web server using the net/http package and implement a custom middleware for logging requests. Follow along with these steps:

Step 1: Set up a Simple HTTP Server

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", homeHandler)
    fmt.Println("Server is starting at :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to the Go HTTP server!")
}

In the code above, we are creating a simple HTTP server that listens on port 8080 and returns "Welcome to the Go HTTP server!" when the root URL is accessed.

Step 2: Create a Middleware

Now, let's create a basic logging middleware function. This middleware will log information about each incoming request.

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL)
        next.ServeHTTP(w, r) // Pass execution to the next handler
    })
}

Step 3: Integrate Middleware with Your HTTP Server

Now let's integrate the middleware we created into our HTTP server.

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", homeHandler)

    // Wrap the multiplexer with the middleware
    wrappedMux := loggingMiddleware(mux)

    fmt.Println("Server is starting at :8080")
    log.Fatal(http.ListenAndServe(":8080", wrappedMux))
}

By wrapping our multiplexer with the loggingMiddleware, each request to our server now gets logged, including the remote address, the HTTP method, and the URL that was accessed.

Conclusion

This article introduced the concept of middleware in Go by creating a basic logging middleware around an HTTP server. Using middleware, we can extend the functionality of our Go HTTP servers with ease.

Next Article: Securing HTTP Servers in Go with HTTPS and Certificates

Previous Article: Routing with `net/http`: Basics of Go Web Servers

Series: Networking and Server

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant