Routing

Rue uses a high-performance radix tree router that achieves ~8ns for static routes and ~27ns for parameterized routes with zero allocations.

Basic Routes

Register routes using HTTP method functions:

go
r := rue.Default()

r.GET("/path", handler)
r.POST("/path", handler)
r.PUT("/path", handler)
r.DELETE("/path", handler)
r.PATCH("/path", handler)
r.HEAD("/path", handler)
r.OPTIONS("/path", handler)

// Match all HTTP methods
r.Any("/path", handler)

Path Parameters

Use :name for named parameters and *name for wildcard parameters:

go
// Named parameter
r.GET("/users/:id", func(c *rue.Context) {
    id := c.Param("id")
    // /users/123 -> id = "123"
    c.JSON(http.StatusOK, rue.H{"id": id})
})

// Multiple parameters
r.GET("/users/:userId/posts/:postId", func(c *rue.Context) {
    userId := c.Param("userId")
    postId := c.Param("postId")
    c.JSON(http.StatusOK, rue.H{
        "user_id": userId,
        "post_id": postId,
    })
})

// Wildcard parameter (catches everything after)
r.GET("/files/*filepath", func(c *rue.Context) {
    path := c.Param("filepath")
    // /files/docs/readme.md -> filepath = "docs/readme.md"
    c.JSON(http.StatusOK, rue.H{"path": path})
})

Route Groups

Group routes with common prefixes and middleware:

go
// Create a group
api := r.Group("/api")
{
    api.GET("/users", listUsers)      // GET /api/users
    api.POST("/users", createUser)    // POST /api/users
}

// Nested groups with middleware
v1 := api.Group("/v1")
v1.Use(authMiddleware)
{
    v1.GET("/posts", listPosts)       // GET /api/v1/posts
    v1.POST("/posts", createPost)     // POST /api/v1/posts
}

// Admin group with multiple middleware
admin := r.Group("/admin")
admin.Use(authMiddleware, adminOnly)
{
    admin.GET("/stats", getStats)
    admin.DELETE("/users/:id", deleteUser)
}

Query Parameters

Access query string parameters:

go
// GET /search?q=golang&page=2&limit=10
r.GET("/search", func(c *rue.Context) {
    // Get single value
    q := c.Query("q")           // "golang"
    
    // Get with default value
    page := c.DefaultQuery("page", "1")    // "2"
    limit := c.DefaultQuery("limit", "20") // "10"
    
    // Get all values for a key
    tags := c.QueryArray("tags")  // []string
    
    c.JSON(http.StatusOK, rue.H{
        "query": q,
        "page":  page,
        "limit": limit,
        "tags":  tags,
    })
})

Static Files

Serve static files and directories:

go
// Serve a directory
r.Static("/assets", "./public/assets")

// Serve a single file
r.StaticFile("/favicon.ico", "./public/favicon.ico")

// Custom file server with more control
r.GET("/files/*filepath", func(c *rue.Context) {
    filepath := c.Param("filepath")
    c.File("./uploads/" + filepath)
})

Redirects

Redirect requests to different URLs:

go
// Temporary redirect (302)
r.GET("/old", func(c *rue.Context) {
    c.Redirect(http.StatusFound, "/new")
})

// Permanent redirect (301)
r.GET("/legacy", func(c *rue.Context) {
    c.Redirect(http.StatusMovedPermanently, "/modern")
})

Route Priority

Routes are matched in the following priority order:

  1. Static routes - Exact path matches
  2. Named parameters - :param patterns
  3. Wildcard parameters - *param patterns
go
r.GET("/users/new", newUserForm)     // Matches first for /users/new
r.GET("/users/:id", getUser)         // Matches /users/123
r.GET("/users/*action", userAction)  // Matches /users/123/edit/profile
⚠️ Route Conflicts

Be careful with overlapping routes. Static routes should be registered before parameterized routes with the same prefix.

Performance

Rue's router is optimized for speed:

Route Type Time Allocations
Static Route ~8ns 0
Param Route ~27ns 1