Kern
Core Concepts

Context API

Learn the Kern Context API for Go request parsing, response writing, file uploads, downloads, headers, cookies, and efficient pooled request handling.

Overview

The Context object is the core of request handling in Kern. It wraps the standard http.ResponseWriter and *http.Request to provide helper methods for reading request data and writing responses.

Context objects are pooled using sync.Pool. This means they are reused across requests to drastically reduce memory allocations and garbage collection overhead in high-throughput applications.

If you are building a Go API server with Kern, the Context API is where most request parsing and response generation happens.

Request Data

Retrieving Methods and Paths

method := c.Method() // e.g., "GET", "POST"
path := c.Path()     // e.g., "/users"

Path Parameters

Get values from the URL path defined with {param} syntax.

id := c.Param("id")

Query Parameters

Get values from the URL query string (e.g., ?search=foo&page=2).

// Get a single value
q := c.Query("search")

// Get with a default value if missing
page := c.DefaultQuery("page", "1")

Form Data

Retrieve values from POST forms (application/x-www-form-urlencoded or multipart/form-data).

username := c.Form("username")
password := c.Form("password")

File Uploads

Handle multipart file uploads easily.

fileHeader, err := c.File("avatar")
if err != nil {
    // Handle error (no file uploaded, etc.)
    c.Text(400, "File required")
    return
}
// Use standard library methods to open/save the file
// e.g., file, _ := fileHeader.Open()

Saving Uploaded Files

Save uploaded files to disk with automatic content handling:

// Save file to ./uploads/avatar.png
err := c.SaveFile(fileHeader, "./uploads/avatar.png")
if err != nil {
    c.JSON(500, map[string]string{"error": "Failed to save file"})
    return
}
c.JSON(200, map[string]string{"message": "File saved"})

File Downloads

Send files for download with proper headers:

// Download a file with custom name
err := c.DownloadFile("./files/report.pdf", "report-2024.pdf")

Streaming Files

Stream large files efficiently with range request support:

// Stream video/audio with range support (partial content)
err := c.StreamFile("./files/video.mp4")

Supports HTTP range requests for seeking and resumable downloads.

Serving Static Files

Serve static files from a directory with directory listing support:

app.GET("/files/{path...}", func(c *kern.Context) {
    err := c.ServeStatic("./public")
    if err != nil {
        c.Text(404, "File not found")
    }
})

Looking for a complete example? See file-upload and file-download.

Headers and Cookies

// Get a header
userAgent := c.GetHeader("User-Agent")

// Get a cookie
cookie, err := c.Cookie("session_id")

Client IP

Retrieve the client's IP address, respecting X-Forwarded-For and X-Real-IP headers if behind a proxy.

ip := c.ClientIP()

Request Body Binding

Kern provides helpers to decode JSON and XML request bodies directly into Go structs.

type User struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

app.POST("/users", func(c *kern.Context) {
    var user User
    
    // Decode JSON body
    if err := c.DecodeJSON(&user); err != nil {
        c.Text(400, "Invalid JSON")
        return
    }

    c.JSON(201, user)
})

Supported binding methods:

  • DecodeJSON(interface{}): Decodes JSON body.
  • DecodeXML(interface{}): Decodes XML body.
  • Body(): Reads the raw body bytes.

Responses

Kern provides several semantic methods to send responses easily.

JSON response

Sets Content-Type: application/json and encodes the data.

c.JSON(200, map[string]string{"status": "ok"})

Text response

Sets Content-Type: text/plain.

c.Text(200, "Hello %s", "World")

HTML response

Sets Content-Type: text/html.

c.HTML(200, "<h1>Hello</h1>")

XML response

Sets Content-Type: application/xml.

c.XML(200, &data)

Raw Data

Send raw bytes with a custom content type.

c.Data(200, "application/octet-stream", []byte("binary data"))

Redirects

Redirect the client to a new URL.

c.Redirect(302, "/login")

Setting Headers and Cookies

c.SetHeader("X-Custom-Header", "value")

c.SetCookie(&http.Cookie{
    Name:  "token",
    Value: "12345",
    Path:  "/",
})

When to use Context helpers

  • Use Param, Query, and Form for fast request-field access.
  • Use DecodeJSON and DecodeXML for request body binding.
  • Use JSON, Text, HTML, and Data for explicit response generation.
  • Use file helpers for upload, download, and streaming workflows.

Testing

Kern provides a NewTestClient to simplify handler testing without starting a real HTTP server.

Basic Setup

import (
    "testing"
    "github.com/mobentum/kern"
)

func TestMyHandler(t *testing.T) {
    app := kern.New()
    app.GET("/hello/{name}", func(c *kern.Context) {
        _ = c.JSON(200, map[string]string{"message": "Hello " + c.Param("name")})
    })

    client := kern.NewTestClient(app)
    res := client.Get("/hello/kern")

    if res.Code != 200 {
        t.Fatalf("got %d, want 200", res.Code)
    }
}

Available Methods

  • Get(path) — sends a GET request
  • Post(path, body) — sends a POST request
  • PostJSON(path, payload) — sends a POST with JSON body and Content-Type header
  • Put(path, body) — sends a PUT request
  • Delete(path) — sends a DELETE request
  • Request(method, path, body) — sends a request with arbitrary method
  • Do(req) — sends a pre-built *http.Request
  • WithHeader(key, value) — sets a default header on all subsequent requests

Default Headers

client := kern.NewTestClient(app).
    WithHeader("Authorization", "Bearer test-token")

res := client.Get("/protected")

JSON Body

type input struct {
    Name string `json:"name"`
}

client := kern.NewTestClient(app)
res := client.PostJSON("/users", input{Name: "alice"})

FAQ

Is Kern Context compatible with net/http?

Yes. Kern wraps the standard http.ResponseWriter and *http.Request instead of replacing Go's HTTP model.

Why does Kern pool Context objects?

Pooling reduces allocations and garbage collection pressure on hot request paths.

Where should I go next?

Read Routing, Middleware, and Architecture Flow to understand how Context fits into full request handling.