Requests
Handling Incoming Requests
Section titled “Handling Incoming Requests”Every handler in Jazzy receives a Context object, which provides simple ways to access incoming data from the client.
Request Input
Section titled “Request Input”Unified Access: input()
Section titled “Unified Access: input()”The input() helper simplifies data retrieval by checking both query string parameters and JSON bodies automatically.
proc search(ctx: Context) {.async.} = # Works for /search?q=query OR {"q": "query"} let query = ctx.input("q")
# With a default value let page = ctx.input("page", "1")
ctx.text("Searching for: " & query & " (Page " & page & ")")Route Parameters: param()
Section titled “Route Parameters: param()”For dynamic routes (e.g., Route.get("/users/:id", ...)), use the param() helper to retrieve values from the URL path.
proc showUser(ctx: Context) {.async.} = let id = ctx.param("id") ctx.text("Viewing user with ID: " & id)Type-Safe Body Parsing: bodyAs()
Section titled “Type-Safe Body Parsing: bodyAs()”If you want to parse the entire request body into a typed object, use bodyAs. This is ideal for structured API payloads.
type UserDto = object username: string age: int
proc create(ctx: Context) {.async.} = let dto = ctx.bodyAs(UserDto) # dto.username and dto.age are now typed values! echo dto.usernameHeaders and IP
Section titled “Headers and IP”Accessing Request Headers
Section titled “Accessing Request Headers”You can access raw request headers directly from the ctx.request.headers table.
proc debugHeaders(ctx: Context) {.async.} = if ctx.request.headers.hasKey("User-Agent"): let ua = ctx.request.headers["User-Agent"] ctx.text("Your browser is: " & ua)Client IP: ip()
Section titled “Client IP: ip()”Retrieves the client’s IP address. It automatically detects and respects the X-Forwarded-For or X-Real-IP headers if TRUST_PROXY=true is set in your .env.
proc checkIp(ctx: Context) {.async.} = let ipAddress = ctx.ip() ctx.text("Your IP is: " & ipAddress)File Uploads
Section titled “File Uploads”Jazzy makes handling multi-part file uploads simple. Use the file() helper to retrieve uploaded files.
proc upload(ctx: Context) {.async.} = let myFile = ctx.file("avatar")
if myFile.filename.len > 0: # myFile.filename: "photo.jpg" # myFile.contentType: "image/jpeg" # myFile.content: "raw file bytes..."
# Save the file writeFile("uploads/" & myFile.filename, myFile.content) ctx.text("File uploaded successfully!") else: ctx.status(400).text("No file uploaded.")