In web development, managing HTTP request and response headers is crucial for handling data, security, and metadata. This article provides a step-by-step guide on setting headers using the httprouter library in Golang. With this guide, even beginners can grasp the concept with ease.
Prerequisites
Before getting started, ensure you have the following:
- Golang Installed: Make sure Go is installed on your system.
- New Project Setup: Create a new project with a basic file structure.
- Httprouter Library: Install the httprouter library with the following command:
go get github.com/julienschmidt/httprouter
Step 1: Setting Up the Project Structure
Create the following project structure:
project/
├── main.go
└── handlers/
└── headers.go
Step 2: Setting Headers in Responses
Response headers are sent to the client via the http.ResponseWriter
object. Let’s add a handler to set response headers.
1. Creating the Handlers File
Open handlers/headers.go
and add the following code:
package handlers
import (
"net/http"
"github.com/julienschmidt/httprouter"
)
// ResponseHeaderHandler adds headers to the response
func ResponseHeaderHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Custom-Header", "Learning Golang")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message":"Headers set successfully!"}`))
}
2. Connecting the Handler in main.go
Open main.go
and add the following handler:
package main
import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
"project/handlers"
)
func main() {
router := httprouter.New()
// Add the response header handler
router.GET("/set-response-header", handlers.ResponseHeaderHandler)
log.Println("Server running at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
3. Testing the Endpoint
Run the server:
go run main.go
Access the endpoint via a browser or use curl
:
curl -i http://localhost:8080/set-response-header
The response will display the headers that have been set.
Step 3: Setting Headers in Requests
To manipulate request headers, we can use the http.Request
object. Here, we’ll create middleware that reads and processes request headers.
1. Adding Middleware
Open handlers/headers.go
again and add the following function:
// RequestHeaderHandler processes headers from the request
func RequestHeaderHandler(next httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
headerValue := r.Header.Get("X-Requested-By")
if headerValue == "" {
http.Error(w, "X-Requested-By header missing", http.StatusBadRequest)
return
}
next(w, r, ps)
}
}
2. Adding Middleware to main.go
Modify main.go
to use the middleware:
router.GET("/validate-request-header", handlers.RequestHeaderHandler(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Write([]byte("Header valid!"))
}))
3. Testing the Endpoint
Run the server again and use curl
:
curl -i -H "X-Requested-By: ClientApp" http://localhost:8080/validate-request-header
If the header is valid, the response will be:
Header valid!
If the header is missing, the response will show an error:
X-Requested-By header missing
Step 4: Writing Unit Tests
Writing unit tests ensures our functions work as expected.
1. Testing ResponseHeaderHandler
Create handlers/headers_test.go
and add the following test:
package handlers
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/julienschmidt/httprouter"
)
func TestResponseHeaderHandler(t *testing.T) {
req := httptest.NewRequest("GET", "/set-response-header", nil)
w := httptest.NewRecorder()
params := httprouter.Params{}
ResponseHeaderHandler(w, req, params)
resp := w.Result()
if resp.Header.Get("X-Custom-Header") != "Learning Golang" {
t.Errorf("Expected X-Custom-Header to be Learning Golang, got %s", resp.Header.Get("X-Custom-Header"))
}
}
2. Testing RequestHeaderHandler
func TestRequestHeaderHandler(t *testing.T) {
handler := RequestHeaderHandler(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Write([]byte("Header valid!"))
})
req := httptest.NewRequest("GET", "/validate-request-header", nil)
w := httptest.NewRecorder()
params := httprouter.Params{}
// Case: Missing Header
handler(w, req, params)
if w.Code != http.StatusBadRequest {
t.Errorf("Expected status 400, got %d", w.Code)
}
// Case: Valid Header
req.Header.Set("X-Requested-By", "ClientApp")
w = httptest.NewRecorder()
handler(w, req, params)
if w.Code != http.StatusOK {
t.Errorf("Expected status 200, got %d", w.Code)
}
}
Run the tests using:
go test ./handlers
Conclusion
With httprouter
, you can easily set headers on HTTP requests and responses. Managing headers is crucial for client-server communication, including security enforcement, caching control, and metadata handling.
For those looking to dive deeper, explore concepts like middleware chaining to manage multiple logic flows modularly. Additionally, consider using debugging tools like Postman or Insomnia to visually test headers, or add logging to your middleware to track headers during development.
We hope this guide helps you better understand header management in Golang web development. If you have any questions, feel free to discuss!
You can also explore related articles: