Skip to main content
Lightning gives you a clean Context API to access every part of an incoming request. All methods live on the *Context value passed to your handler.

URL Parameters

Define dynamic segments in your route pattern with a : prefix. Read them at runtime with ctx.Param().
app.Get("/users/:id", func(ctx *lightning.Context) {
    id := ctx.Param("id") // string

    // Typed conversions
    idInt, err := ctx.ParamInt("id")
    if err != nil {
        ctx.JSONError(lightning.StatusBadRequest, "invalid id")
        return
    }

    ctx.JSON(lightning.StatusOK, lightning.Map{"id": idInt})
})
Typed param helpers return (T, error) so you can handle malformed values explicitly:
MethodReturn type
ctx.ParamInt(key)(int, error)
ctx.ParamInt64(key)(int64, error)
ctx.ParamUInt(key)(uint, error)
ctx.ParamUInt64(key)(uint64, error)
ctx.ParamFloat32(key)(float32, error)
ctx.ParamFloat64(key)(float64, error)
Use ctx.Params() to get all URL parameters as map[string]string at once.

Query Parameters

Read query string values with ctx.Query() for strings or the typed helpers for numeric and boolean values.
app.Get("/search", func(ctx *lightning.Context) {
    q := ctx.Query("q") // string, empty string if absent

    page, err := ctx.QueryInt("page")
    if err != nil {
        ctx.JSONError(lightning.StatusBadRequest, "page must be an integer")
        return
    }

    active, err := ctx.QueryBool("active")
    if err != nil {
        ctx.JSONError(lightning.StatusBadRequest, "active must be a boolean")
        return
    }

    ctx.JSON(lightning.StatusOK, lightning.Map{
        "q":      q,
        "page":   page,
        "active": active,
    })
})
All typed query helpers return zero values (not errors) when the key is absent, and return an error only when the value is present but cannot be parsed. Full set of typed query helpers:
MethodReturn type
ctx.QueryInt(key)(int, error)
ctx.QueryInt8(key)(int8, error)
ctx.QueryInt32(key)(int32, error)
ctx.QueryInt64(key)(int64, error)
ctx.QueryUInt(key)(uint, error)
ctx.QueryUInt8(key)(uint8, error)
ctx.QueryUInt32(key)(uint32, error)
ctx.QueryUInt64(key)(uint64, error)
ctx.QueryFloat32(key)(float32, error)
ctx.QueryFloat64(key)(float64, error)
ctx.QueryBool(key)(bool, error)
Use ctx.Queries() to get all query parameters as map[string][]string.

Request Body

JSON body

Use ctx.JSONBody(&v) to decode the request body into a struct. Pass true as the second argument to also validate the struct using go-playground/validator struct tags.
type CreateUserRequest struct {
    Name     string `json:"name"     validate:"required"`
    Email    string `json:"email"    validate:"required,email"`
    Password string `json:"password" validate:"required,min=8,max=32"`
}

app.Post("/users", func(ctx *lightning.Context) {
    var req CreateUserRequest
    if err := ctx.JSONBody(&req, true); err != nil {
        ctx.Fail(-1, err.Error())
        return
    }

    ctx.Success(req)
})
Omit the second argument (or pass false) to skip validation and decode only:
err := ctx.JSONBody(&req)        // decode, no validation
err := ctx.JSONBody(&req, true)  // decode + validate

Raw and string body

app.Post("/webhook", func(ctx *lightning.Context) {
    raw := ctx.RawBody()    // []byte
    str := ctx.StringBody() // string

    ctx.Text(lightning.StatusOK, "received")
})

Headers

Read a single request header by name with ctx.Header(). Header names are case-insensitive.
app.Get("/protected", func(ctx *lightning.Context) {
    auth := ctx.Header("Authorization")
    if auth == "" {
        ctx.JSONError(lightning.StatusUnauthorized, "missing authorization header")
        return
    }

    ctx.JSON(lightning.StatusOK, lightning.Map{"token": auth})
})
Use ctx.Headers() to get all request headers as map[string]string.

Cookies

Read a single cookie by name with ctx.Cookie(). It returns *fasthttp.Cookie (or nil if the cookie is not present).
app.Get("/dashboard", func(ctx *lightning.Context) {
    session := ctx.Cookie("session_id")
    if session == nil {
        ctx.JSONError(lightning.StatusUnauthorized, "no session")
        return
    }

    // cookie.Key() and cookie.Value() return []byte
    ctx.JSON(lightning.StatusOK, lightning.Map{
        "session": string(session.Value()),
    })
})
Use ctx.Cookies() to iterate over all cookies in the request:
cookies := ctx.Cookies() // []*fasthttp.Cookie
for _, c := range cookies {
    fmt.Println(string(c.Key()), string(c.Value()))
}

Complete Example: POST Handler with JSON Validation

The following handler parses a JSON body, validates it, and returns a structured response.
package main

import (
    "github.com/go-labx/lightning"
)

type RegisterRequest struct {
    Name     string `json:"name"     validate:"required"`
    Email    string `json:"email"    validate:"required,email"`
    Password string `json:"password" validate:"required,min=8,max=32"`
}

func main() {
    app := lightning.DefaultApp()

    app.Post("/register", func(ctx *lightning.Context) {
        var req RegisterRequest

        // Decode the JSON body and run validator struct tags
        if err := ctx.JSONBody(&req, true); err != nil {
            ctx.Fail(-1, err.Error())
            return
        }

        // Use the validated data
        ctx.Success(lightning.Map{
            "name":  req.Name,
            "email": req.Email,
        })
    })

    app.Run(":8080")
}
Example request:
curl -X POST http://localhost:8080/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice","email":"alice@example.com","password":"secret123"}'
Example response:
{
  "code": 0,
  "message": "ok",
  "data": {
    "name": "Alice",
    "email": "alice@example.com"
  }
}
If validation fails, ctx.JSONBody returns the first validation error as a Go error, and ctx.Fail(-1, err.Error()) sends it back to the client.