Response Handling Patterns
Common Response Handling Strategies
1. Middleware Response Pattern
graph TD
A[HTTP Request] --> B[Middleware]
B --> C{Request Validation}
C -->|Valid| D[Main Handler]
C -->|Invalid| E[Error Response]
D --> F[Response Generation]
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("Incoming request: %s", r.URL.Path)
next.ServeHTTP(w, r)
}
}
Response Composition Patterns
Structured Response Template
type APIResponse struct {
Status int `json:"status"`
Data interface{} `json:"data"`
Message string `json:"message"`
}
func standardResponseHandler(w http.ResponseWriter, r *http.Request) {
response := APIResponse{
Status: http.StatusOK,
Data: getUserData(),
Message: "Successfully retrieved data",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
Error Handling Strategies
Comprehensive Error Response
type ErrorResponse struct {
Code string `json:"error_code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
func handleErrors(w http.ResponseWriter, err error) {
var responseError ErrorResponse
switch {
case errors.Is(err, sql.ErrNoRows):
responseError = ErrorResponse{
Code: "NOT_FOUND",
Message: "Resource not found",
}
w.WriteHeader(http.StatusNotFound)
case err != nil:
responseError = ErrorResponse{
Code: "INTERNAL_ERROR",
Message: "Internal server error",
Details: err.Error(),
}
w.WriteHeader(http.StatusInternalServerError)
}
json.NewEncoder(w).Encode(responseError)
}
Response Handling Techniques
Pattern |
Use Case |
Complexity |
Simple Write |
Small, direct responses |
Low |
Structured Response |
API endpoints |
Medium |
Streaming |
Large data |
High |
Middleware Wrapping |
Request preprocessing |
Medium |
Advanced Response Patterns
Conditional Response Generation
func conditionalResponseHandler(w http.ResponseWriter, r *http.Request) {
switch r.Header.Get("Accept") {
case "application/json":
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(jsonResponse())
case "application/xml":
w.Header().Set("Content-Type", "application/xml")
xml.NewEncoder(w).Encode(xmlResponse())
default:
w.Write([]byte("Default text response"))
}
}
Best Practices
- Use consistent response structures
- Implement comprehensive error handling
- Leverage middleware for request preprocessing
- Consider content negotiation
- Optimize response generation performance
By understanding these patterns, developers can create robust and flexible response handling mechanisms in their LabEx Golang applications.