TypeFunction
HandlerFunc
Function signature for request handlers that process HTTP requests and generate responses.
Type Definition
type HandlerFunc func(req *Request, res *Response)Usage Examples
Basic Handler
Simple handler that responds with plain text.
// Define a handler function
func helloHandler(req *Request, res *Response) {
res.Write("Hello, World!")
res.Send()
}
func main() {
server := SpawnServer()
// Use the handler function
server.Get("/hello", helloHandler)
// Or use an anonymous function
server.Get("/", func(req *Request, res *Response) {
res.Write("Welcome to Squirrel!")
res.Send()
})
server.Listen(":8080")
}JSON API Handler
Handler that processes JSON data and returns JSON responses.
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func createUserHandler(req *Request, res *Response) {
// Read request body
body, err := req.ReadBodyAsString()
if err != nil {
res.SetStatus(400)
res.JSON(map[string]string{"error": "Invalid request body"})
res.Send()
return
}
// Parse JSON (simplified - you'd use json.Unmarshal in real code)
if body == "" {
res.SetStatus(400)
res.JSON(map[string]string{"error": "Empty request body"})
res.Send()
return
}
// Create user (simulated)
user := User{
ID: 123,
Name: "John Doe",
Email: "john@example.com",
}
res.SetStatus(201)
res.JSON(user)
res.Send()
}
func main() {
server := SpawnServer()
server.Post("/api/users", createUserHandler)
server.Listen(":8080")
}Handler with URL Parameters
Handler that extracts and uses URL parameters.
func getUserHandler(req *Request, res *Response) {
userID := req.Param("id")
if userID == "" {
res.SetStatus(400)
res.JSON(map[string]string{"error": "User ID is required"})
res.Send()
return
}
// Simulate user lookup
if userID == "404" {
res.SetStatus(404)
res.JSON(map[string]string{"error": "User not found"})
res.Send()
return
}
user := User{
ID: 123,
Name: "John Doe",
Email: "john@example.com",
}
res.JSON(user)
res.Send()
}
func main() {
server := SpawnServer()
// Route with parameter
server.Get("/api/users/:id", getUserHandler)
// Multiple parameters
server.Get("/api/users/:userId/posts/:postId", func(req *Request, res *Response) {
userID := req.Param("userId")
postID := req.Param("postId")
res.JSON(map[string]string{
"userId": userID,
"postId": postID,
"message": fmt.Sprintf("Post %s by user %s", postID, userID),
})
res.Send()
})
server.Listen(":8080")
}Handler with Query Parameters
Handler that processes query string parameters.
func searchHandler(req *Request, res *Response) {
// Get all query parameters
queries := req.Query()
// Get specific query parameters
searchTerms := req.Queries["q"] // []string
categories := req.Queries["category"] // []string
limitStr := req.Queries["limit"] // []string
// Process search terms
if len(searchTerms) == 0 {
res.SetStatus(400)
res.JSON(map[string]string{"error": "Search query 'q' is required"})
res.Send()
return
}
// Parse limit (default to 10)
limit := 10
if len(limitStr) > 0 {
if parsedLimit, err := strconv.Atoi(limitStr[0]); err == nil {
limit = parsedLimit
}
}
// Build response
response := map[string]interface{}{
"searchTerms": searchTerms,
"categories": categories,
"limit": limit,
"results": []string{"result1", "result2", "result3"},
}
res.JSON(response)
res.Send()
}
// Usage: GET /search?q=golang&q=web&category=framework&limit=5Error Handling Pattern
Best practices for error handling in handlers.
func robustHandler(req *Request, res *Response) {
// Defer recovery for unexpected panics
defer func() {
if r := recover(); r != nil {
res.SetStatus(500)
res.JSON(map[string]string{
"error": "Internal server error",
"message": "An unexpected error occurred",
})
res.Send()
}
}()
// Validate request method (if needed)
if req.Method != "POST" {
res.SetStatus(405) // Method Not Allowed
res.SetHeader("Allow", "POST")
res.JSON(map[string]string{"error": "Method not allowed"})
res.Send()
return
}
// Check content length
if req.ContentLength > 1024*1024 { // 1MB limit
res.SetStatus(413) // Payload Too Large
res.JSON(map[string]string{"error": "Request body too large"})
res.Send()
return
}
// Process request
body, err := req.ReadBodyAsString()
if err != nil {
res.SetStatus(400)
res.JSON(map[string]string{
"error": "Failed to read request body",
"details": err.Error(),
})
res.Send()
return
}
// Success response
res.SetStatus(200)
res.JSON(map[string]string{
"message": "Request processed successfully",
"data": body,
})
res.Send()
}HandlerFunc is the core interface for processing requests in Squirrel Framework. Always ensure you call
res.Send() and handle errors appropriately with proper HTTP status codes.