| 7 | ) |
| 8 | |
| 9 | func main() { |
| 10 | app := pine.New() |
| 11 | |
| 12 | // Public route — no middleware, no prefix. |
| 13 | app.Get("/health", func(c *pine.Ctx) error { |
| 14 | return c.JSON(map[string]string{"status": "ok"}) |
| 15 | }) |
| 16 | |
| 17 | // v1 group — all routes share the /v1 prefix. |
| 18 | // The logger middleware runs for every route under /v1. |
| 19 | v1 := app.Group("/v1", requestLogger()) |
| 20 | |
| 21 | // /v1/users — public within v1. |
| 22 | users := v1.Group("/users") |
| 23 | users.Get("/", func(c *pine.Ctx) error { |
| 24 | return c.JSON([]map[string]string{ |
| 25 | {"id": "1", "name": "Alice"}, |
| 26 | {"id": "2", "name": "Bob"}, |
| 27 | }) |
| 28 | }) |
| 29 | users.Get("/:id", func(c *pine.Ctx) error { |
| 30 | return c.JSON(map[string]string{"id": c.Params("id")}) |
| 31 | }) |
| 32 | users.Post("/", func(c *pine.Ctx) error { |
| 33 | return c.Status(201).JSON(map[string]string{"created": "true"}) |
| 34 | }) |
| 35 | |
| 36 | // /v1/admin — nested group with an additional API-key check. |
| 37 | // Both requestLogger (inherited from v1) and requireAPIKey run here. |
| 38 | admin := v1.Group("/admin", requireAPIKey()) |
| 39 | admin.Get("/stats", func(c *pine.Ctx) error { |
| 40 | return c.JSON(map[string]any{ |
| 41 | "requests": 1024, |
| 42 | "uptime": "3d 4h", |
| 43 | }) |
| 44 | }) |
| 45 | admin.Delete("/cache", func(c *pine.Ctx) error { |
| 46 | return c.JSON(map[string]string{"cache": "cleared"}) |
| 47 | }) |
| 48 | |
| 49 | log.Fatal(app.Start(":3000")) |
| 50 | } |
| 51 | |
| 52 | // requestLogger is a middleware that logs each request method and path. |
| 53 | // It runs for every route registered on the group it is attached to. |