Documentation

Request & Response Objects

Updated
Browse documentation

Published 2026-08-13. V2 is a prerelease; the web core is release-gated and other previews are named separately. What beta means.

Read this page as HTML, Markdown, or structured JSON—or open the published Markdown with an AI assistant. Gemini receives the prompt through your clipboard because its signed-out page does not reliably prefill URL text; paste when the new tab opens. External assistants need the public site URL.

Request & Response Objects

Every Amber controller delegates request and response to the current HTTP::Server::Context. Use Amber's controller helpers for ordinary rendering, redirects, and negotiated responses; reach for the underlying Crystal objects when you need a header, method, resource, or status directly.

Request

request is Crystal's HTTP::Request with Amber routing extensions.

File: src/controllers/diagnostics_controller.cr — place this action inside DiagnosticsController, then register it in config/routes.cr.

Crystal
class DiagnosticsController < ApplicationController
  def show
    method = request.method
    resource = request.resource
    user_agent = request.headers["User-Agent"]?
    query = request.query

    respond_with do
      json({method: method, resource: resource, user_agent: user_agent, query: query}.to_json)
    end
  end
end

Common controller-level helpers include:

Helper Result
get?, post?, put?, patch?, delete?, head? Whether the request uses that HTTP method
params Amber route, query, and form parameters
format The requested response format inferred from the path or headers
port The request port
requested_url The parsed request URL
cookies Amber's cookie store
session, flash The current session and flash stores

The raw request body is an IO. A parser or request schema is usually a better boundary for JSON or form input than manually reading the stream in each action.

Response

response is Crystal's HTTP::Server::Response. Its most useful direct properties are status_code, headers, and content_type.

File: src/controllers/health_controller.cr — place this action inside HealthController, then register it in config/routes.cr.

Crystal
class HealthController < ApplicationController
  def show
    response.headers["Cache-Control"] = "no-store"
    set_response(
      body: "ok",
      status_code: 200,
      content_type: "text/plain"
    )
  end
end

File: a controller action under src/controllers/ — use respond_with when that action offers these representations.

Crystal
respond_with do
  html render("show.ecr")
  json({status: "ok"}.to_json)
  text "ok"
end

File: a controller filter or action under src/controllers/ — use halt! when the pipeline must stop with a plain response.

Crystal
halt!(403, "forbidden") unless authorized?

File: a controller action under src/controllers/ — use the redirect helper rather than setting a Location header by hand.

Crystal
redirect_to location: "/login", status: 302

For the upstream object APIs, see Crystal's HTTP::Request and HTTP::Server::Response reference. Amber-specific helpers and schema integration should remain the first choice when they express the intent.