Route Groups¶
Route groups help organize routes with shared prefixes and middleware.
Basic Groups¶
Create a group with a prefix:
api := app.Group("/api")
{
api.GET("/users", listUsers) // GET /api/users
api.POST("/users", createUser) // POST /api/users
api.GET("/posts", listPosts) // GET /api/posts
}
Nested Groups¶
Groups can be nested:
api := app.Group("/api")
{
v1 := api.Group("/v1")
{
v1.GET("/users", listUsersV1) // GET /api/v1/users
v1.GET("/posts", listPostsV1) // GET /api/v1/posts
}
v2 := api.Group("/v2")
{
v2.GET("/users", listUsersV2) // GET /api/v2/users
v2.GET("/posts", listPostsV2) // GET /api/v2/posts
}
}
Group Middleware¶
Add middleware to a group:
// Method 1: In Group() call
api := app.Group("/api", authMiddleware)
// Method 2: Using Use()
api := app.Group("/api")
api.Use(authMiddleware)
// Both apply to all routes in the group
api.GET("/users", listUsers) // Has authMiddleware
api.POST("/users", createUser) // Has authMiddleware
Multiple Middleware¶
api := app.Group("/api")
api.Use(
middleware.RateLimit(rateLimitConfig),
authMiddleware,
loggingMiddleware,
)
Middleware Inheritance¶
Nested groups inherit parent middleware:
api := app.Group("/api")
api.Use(authMiddleware) // Applied to all /api routes
admin := api.Group("/admin")
admin.Use(adminMiddleware) // Applied in addition to authMiddleware
admin.GET("/users", adminUsers) // Has both authMiddleware AND adminMiddleware
Common Patterns¶
API Versioning¶
func setupRoutes(app *marten.App) {
// V1 API
v1 := app.Group("/api/v1")
v1.Use(v1Middleware)
setupV1Routes(v1)
// V2 API
v2 := app.Group("/api/v2")
v2.Use(v2Middleware)
setupV2Routes(v2)
}
func setupV1Routes(g *marten.Group) {
g.GET("/users", listUsersV1)
g.POST("/users", createUserV1)
}
func setupV2Routes(g *marten.Group) {
g.GET("/users", listUsersV2)
g.POST("/users", createUserV2)
}
Public vs Protected Routes¶
// Public routes
app.GET("/", home)
app.GET("/health", health)
app.POST("/auth/login", login)
app.POST("/auth/register", register)
// Protected routes
api := app.Group("/api")
api.Use(authMiddleware)
{
api.GET("/me", getMe)
api.GET("/profile", getProfile)
api.PUT("/profile", updateProfile)
}
// Admin routes
admin := app.Group("/admin")
admin.Use(authMiddleware, adminMiddleware)
{
admin.GET("/dashboard", dashboard)
admin.GET("/users", adminListUsers)
admin.DELETE("/users/:id", adminDeleteUser)
}
Resource Groups¶
func registerUserRoutes(app *marten.App) {
users := app.Group("/users")
{
users.GET("", listUsers)
users.POST("", createUser)
users.GET("/:id", getUser)
users.PUT("/:id", updateUser)
users.DELETE("/:id", deleteUser)
// Nested resources
users.GET("/:id/posts", getUserPosts)
users.POST("/:id/posts", createUserPost)
}
}
func registerPostRoutes(app *marten.App) {
posts := app.Group("/posts")
{
posts.GET("", listPosts)
posts.POST("", createPost)
posts.GET("/:id", getPost)
posts.PUT("/:id", updatePost)
posts.DELETE("/:id", deletePost)
// Nested resources
posts.GET("/:id/comments", getPostComments)
posts.POST("/:id/comments", createPostComment)
}
}
Feature Modules¶
// users/routes.go
package users
func RegisterRoutes(app *marten.App) {
g := app.Group("/users")
g.Use(middleware.Auth)
g.GET("", List)
g.POST("", Create)
g.GET("/:id", Get)
g.PUT("/:id", Update)
g.DELETE("/:id", Delete)
}
// main.go
func main() {
app := marten.New()
users.RegisterRoutes(app)
posts.RegisterRoutes(app)
comments.RegisterRoutes(app)
app.Run(":3000")
}
Webhooks¶
webhooks := app.Group("/webhooks")
webhooks.Use(webhookAuthMiddleware)
{
webhooks.POST("/github", handleGitHub)
webhooks.POST("/stripe", handleStripe)
webhooks.POST("/slack", handleSlack)
}
Group Methods¶
Groups support all HTTP methods:
g := app.Group("/api")
g.GET(path, handler)
g.POST(path, handler)
g.PUT(path, handler)
g.DELETE(path, handler)
g.PATCH(path, handler)
g.Handle(method, path, handler)
Route-Specific Middleware in Groups¶
Add middleware to specific routes within a group:
api := app.Group("/api")
api.Use(authMiddleware)
// All routes have authMiddleware
api.GET("/users", listUsers)
api.POST("/users", createUser)
// This route also has adminMiddleware
api.DELETE("/users/:id", deleteUser, adminMiddleware)
Best Practices¶
1. Use Meaningful Prefixes¶
// Good
app.Group("/api/v1")
app.Group("/admin")
app.Group("/webhooks")
// Avoid
app.Group("/a")
app.Group("/stuff")
2. Keep Groups Focused¶
// Good - each group has a clear purpose
users := app.Group("/users")
posts := app.Group("/posts")
// Avoid - mixing unrelated routes
misc := app.Group("/misc")
misc.GET("/users", listUsers)
misc.GET("/weather", getWeather)
3. Apply Middleware at the Right Level¶
// Global middleware for all routes
app.Use(middleware.Logger, middleware.Recover)
// API middleware for API routes
api := app.Group("/api")
api.Use(middleware.RateLimit(cfg))
// Auth middleware for protected routes
protected := api.Group("/protected")
protected.Use(authMiddleware)
4. Document Your Groups¶
// Public API endpoints
// No authentication required
public := app.Group("/api/public")
// Protected API endpoints
// Requires valid JWT token
protected := app.Group("/api")
protected.Use(jwtMiddleware)
// Admin endpoints
// Requires admin role
admin := app.Group("/admin")
admin.Use(jwtMiddleware, adminMiddleware)