Lightning uses a trie-based router that resolves routes by HTTP method and path. You register routes on an *Application value returned by lightning.NewApp() or lightning.DefaultApp().
Registering routes
Each HTTP method has a dedicated registration function. Pass the URL pattern as the first argument, then one or more handler functions.
app := lightning.NewApp()
app.Get("/users", listUsers)
app.Post("/users", createUser)
app.Put("/users/:id", replaceUser)
app.Patch("/users/:id", updateUser)
app.Delete("/users/:id", deleteUser)
app.Head("/users/:id", headUser)
app.Options("/users", optionsUsers)
All handler functions have the signature func(*lightning.Context).
Full example
package main
import "github.com/go-labx/lightning"
func main() {
app := lightning.NewApp()
app.Get("/", func(ctx *lightning.Context) {
ctx.Text(lightning.StatusOK, "welcome")
})
app.Post("/articles", func(ctx *lightning.Context) {
// create article
ctx.JSON(lightning.StatusOK, lightning.Map{"status": "created"})
})
app.Put("/articles/:id", func(ctx *lightning.Context) {
// replace article
ctx.JSON(lightning.StatusOK, lightning.Map{"status": "replaced"})
})
app.Patch("/articles/:id/title", func(ctx *lightning.Context) {
// update title only
ctx.JSON(lightning.StatusOK, lightning.Map{"status": "updated"})
})
app.Delete("/articles/:id", func(ctx *lightning.Context) {
// delete article
ctx.JSON(lightning.StatusOK, lightning.Map{"status": "deleted"})
})
app.Run()
}
URL parameters
Prefix a path segment with : to make it a named parameter. Lightning captures the segment and makes it available via ctx.Param.
/users/:id → matches /users/42
/posts/:slug/edit → matches /posts/hello-world/edit
Reading parameters
| Method | Returns |
|---|
ctx.Param(key string) string | Raw string value |
ctx.ParamInt(key string) (int, error) | Parsed as int |
ctx.ParamInt64(key string) (int64, error) | Parsed as int64 |
ctx.ParamUInt(key string) (uint, error) | Parsed as uint |
ctx.ParamUInt64(key string) (uint64, error) | Parsed as uint64 |
ctx.ParamFloat32(key string) (float32, error) | Parsed as float32 |
ctx.ParamFloat64(key string) (float64, error) | Parsed as float64 |
ctx.Params() map[string]string | All parameters |
app.Get("/users/:id", func(ctx *lightning.Context) {
id, err := ctx.ParamInt("id")
if err != nil {
ctx.JSONError(lightning.StatusBadRequest, "invalid id")
return
}
ctx.JSON(lightning.StatusOK, lightning.Map{"id": id})
})
app.Get("/posts/:slug/edit", func(ctx *lightning.Context) {
slug := ctx.Param("slug") // e.g. "hello-world"
ctx.JSON(lightning.StatusOK, lightning.Map{"slug": slug})
})
Wildcard routes
Prefix a path segment with * to match the rest of the URL as a single named value. The wildcard captures everything from that segment to the end of the path, joined with /.
/files/*path → matches /files/docs/api/v1.html
ctx.Param("path") == "docs/api/v1.html"
app.Get("/files/*path", func(ctx *lightning.Context) {
filePath := ctx.Param("path")
ctx.JSON(lightning.StatusOK, lightning.Map{"path": filePath})
})
A wildcard segment must be the last segment in a pattern. Putting additional segments after *param has no effect.
Dynamic method registration with AddRoute
When you need to register a route for an HTTP method that is determined at runtime, use app.AddRoute directly.
// Signature
func (app *Application) AddRoute(method string, pattern string, handlers []HandlerFunc)
routes := []struct {
method string
pattern string
}{
{"GET", "/health"},
{"POST", "/events"},
}
for _, r := range routes {
r := r // capture loop variable
app.AddRoute(r.method, r.pattern, []lightning.HandlerFunc{
func(ctx *lightning.Context) {
ctx.JSON(lightning.StatusOK, lightning.Map{"method": r.method})
},
})
}
AddRoute prepends all global middleware registered with app.Use() before the handlers you supply, matching the behaviour of the typed shorthand methods.