Routing Guide

Learn how to define routes, handle path parameters, and organize your applications URL structure with Squirrel.

RoutingHTTP MethodsPath Parameters
Basic Routing
Define simple routes to handle different URL paths
package main

import (
    "fmt"
    "net/http"
    "github.com/squirrel-land/squirrel"
)

func main() {
    mux := squirrel.NewSqurlMux()
    
    // Basic routes
    mux.HandleFunc("/", homeHandler)
    mux.HandleFunc("/about", aboutHandler)
    mux.HandleFunc("/contact", contactHandler)
    
    http.ListenAndServe(":8080", mux)
}

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

func aboutHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "About us page")
}

func contactHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Contact us at contact@example.com")
}
Path Parameters
Capture dynamic values from URL paths
package main

import (
    "fmt"
    "net/http"
    "github.com/squirrel-land/squirrel"
)

func main() {
    mux := squirrel.NewSqurlMux()
    
    // Single parameter
    mux.HandleFunc("/user/{id}", userHandler)
    
    // Multiple parameters
    mux.HandleFunc("/user/{id}/post/{postId}", postHandler)
    
    // Optional parameters with wildcards
    mux.HandleFunc("/files/{path...}", fileHandler)
    
    http.ListenAndServe(":8080", mux)
}

func userHandler(w http.ResponseWriter, r *http.Request) {
    id := squirrel.GetParam(r, "id")
    fmt.Fprintf(w, "User ID: %s", id)
}

func postHandler(w http.ResponseWriter, r *http.Request) {
    userID := squirrel.GetParam(r, "id")
    postID := squirrel.GetParam(r, "postId")
    fmt.Fprintf(w, "User %s, Post %s", userID, postID)
}

func fileHandler(w http.ResponseWriter, r *http.Request) {
    path := squirrel.GetParam(r, "path")
    fmt.Fprintf(w, "File path: %s", path)
}
HTTP Methods
Handle different HTTP methods (GET, POST, PUT, DELETE, etc.)
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "github.com/squirrel-land/squirrel"
)

func main() {
    mux := squirrel.NewSqurlMux()
    
    // Method-specific routes
    mux.Get("/users", getUsersHandler)
    mux.Post("/users", createUserHandler)
    mux.Put("/users/{id}", updateUserHandler)
    mux.Delete("/users/{id}", deleteUserHandler)
    
    // Generic handler with method checking
    mux.HandleFunc("/api/status", func(w http.ResponseWriter, r *http.Request) {
        switch r.Method {
        case http.MethodGet:
            fmt.Fprintf(w, "Status: OK")
        case http.MethodPost:
            fmt.Fprintf(w, "Status updated")
        default:
            http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        }
    })
    
    http.ListenAndServe(":8080", mux)
}

func getUsersHandler(w http.ResponseWriter, r *http.Request) {
    users := []string{"Alice", "Bob", "Charlie"}
    json.NewEncoder(w).Encode(users)
}

func createUserHandler(w http.ResponseWriter, r *http.Request) {
    // Handle user creation
    w.WriteHeader(http.StatusCreated)
    fmt.Fprintf(w, "User created")
}

func updateUserHandler(w http.ResponseWriter, r *http.Request) {
    id := squirrel.GetParam(r, "id")
    fmt.Fprintf(w, "User %s updated", id)
}

func deleteUserHandler(w http.ResponseWriter, r *http.Request) {
    id := squirrel.GetParam(r, "id")
    fmt.Fprintf(w, "User %s deleted", id)
}
Route Groups
Organize related routes with common prefixes and middleware
package main

import (
    "fmt"
    "net/http"
    "github.com/squirrel-land/squirrel"
)

func main() {
    mux := squirrel.NewSqurlMux()
    
    // API v1 routes
    apiV1 := mux.Group("/api/v1")
    apiV1.Use(authMiddleware) // Apply middleware to all routes in group
    apiV1.Get("/users", getUsersHandler)
    apiV1.Post("/users", createUserHandler)
    apiV1.Get("/posts", getPostsHandler)
    
    // API v2 routes
    apiV2 := mux.Group("/api/v2")
    apiV2.Use(authMiddleware)
    apiV2.Use(rateLimitMiddleware)
    apiV2.Get("/users", getUsersV2Handler)
    apiV2.Post("/users", createUserV2Handler)
    
    // Admin routes
    admin := mux.Group("/admin")
    admin.Use(adminAuthMiddleware)
    admin.Get("/dashboard", adminDashboardHandler)
    admin.Get("/users", adminUsersHandler)
    
    http.ListenAndServe(":8080", mux)
}

func authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Check authentication
        token := r.Header.Get("Authorization")
        if token == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}
Advanced Routing Patterns
Complex routing scenarios and best practices
// Subdomain routing
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    host := r.Host
    switch {
    case strings.HasPrefix(host, "api."):
        apiHandler(w, r)
    case strings.HasPrefix(host, "admin."):
        adminHandler(w, r)
    default:
        mainSiteHandler(w, r)
    }
})