Route Groups
Organize related routes under shared URL prefixes for APIs, versioning, admin panels, and modular applications.
Route groups allow routes to share a common URL prefix.
They are useful for:
- API versioning
- modular applications
- admin panels
- internal services
- route organization
- shared middleware
- separating public and private APIs
Instead of repeating the same path prefix on every route, the group automatically prepends it to all child routes.
Creating a Route Group
Use Group(...) to create a grouped router.
api := r.Group("/api/v1")All routes registered inside the group automatically inherit the prefix.
Example:
api.GET("/users", handler)becomes:
/api/v1/usersExample
package main
import (
"fmt"
"log/slog"
"net/http"
"os"
"github.com/netlifeguru/router"
)
func main() {
r := router.New()
api := r.Group("/api/v1")
{
api.HandleFunc("/", "GET POST", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`<h1>/api/v1/</h1>`))
})
api.HandleFunc("/user/{id}", "GET POST", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
userID := ctx.Param("id")
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(fmt.Sprintf(`<h1>/api/v1/user:%s</h1>`, userID)))
})
}
if err := r.ListenAndServe(":8000"); err != nil {
slog.Error("failed to start server", "error", err)
os.Exit(1)
}
}Resulting Routes
The example above creates the following routes:
| Route | Methods |
|---|---|
/api/v1/ | GET, POST |
/api/v1/user/{id} | GET, POST |
The group prefix is automatically prepended to all child routes.
API Versioning
One of the most common uses for route groups is API versioning.
Example:
v1 := r.Group("/api/v1")
v2 := r.Group("/api/v2")This allows multiple API versions to coexist cleanly:
/api/v1/users
/api/v2/userswithout duplicating route logic structure.
Nested Groups
Groups can be nested.
Example:
api := r.Group("/api")
admin := api.Group("/admin")Resulting route:
/api/adminNested groups inherit the full parent prefix automatically.
Group Organization
Using blocks is optional but recommended for readability.
Example:
api := r.Group("/api/v1")
{
api.GET("/users", handler)
api.GET("/posts", handler)
}This keeps grouped routes visually organized in larger applications.
Combining Groups with Middleware
Groups work especially well together with middleware.
Example:
api := r.Group("/api")
api.Use(AuthMiddleware)All routes inside the group automatically inherit the middleware.
This is commonly used for:
- authentication
- authorization
- rate limiting
- logging
- request validation
Group middleware is covered in the dedicated Group Middleware section.
Common Use Cases
| Use Case | Example |
|---|---|
| API Versioning | /api/v1 |
| Admin Dashboard | /admin |
| Internal Services | /internal |
| Public API | /public |
| GraphQL Services | /graphql |
| Webhooks | /webhooks |
| Monitoring | /metrics |
Notes
Route groups only affect URL prefixes and inherited middleware.
They do not create isolated router instances.
For isolated middleware scopes and modular middleware chains, see the dedicated middleware grouping features such as With(...).
Wildcard Routes
Capture and forward dynamic URL branches using wildcard routes for static files, frontend applications, mounted services, and catch-all handlers.
Middleware
Use built-in and custom middleware for logging, request IDs, real client IP detection, CORS, compression, content validation, caching, and request normalization.