Response
The Response is an immutable case class representing an HTTP response.
Structure
Section titled “Structure”case class Response( status: Int = 200, headers: ResponseHeaders = ResponseHeaders.empty, body: ResponseBody = EmptyBody,)Factory Methods
Section titled “Factory Methods”The Response companion object provides factory methods for common response types:
case class User(name: String) derives JsonEncoder
Response.json(User("Alice")) // 200 with JSON bodyResponse.json(User("Alice"), status = 201) // 201 CreatedResponse.json(Map("error" -> "oops"), status = 400)Response.text("Hello World") // 200 with text/plainResponse.text("Created", status = 201)Binary
Section titled “Binary”Response.binary(buffer) // 200 with application/octet-streamResponse.binary(buffer, status = 200)Stream
Section titled “Stream”val fileStream = fs.createReadStream("video.mp4")Response.stream(fileStream, additionalHeaders = Seq( "Content-Type" -> "video/mp4"))No Content
Section titled “No Content”Response.noContent() // 204 with empty bodyResponse Body Types
Section titled “Response Body Types”sealed trait ResponseBody
case class StringBody(content: String, data: Buffer) extends ResponseBodycase class BufferBody(content: Buffer) extends ResponseBodycase class ReadableStreamBody(readable: ReadableStream) extends ResponseBodycase object EmptyBody extends ResponseBodyHeaders
Section titled “Headers”ResponseHeaders is a case-insensitive, multi-value header container:
// Add a single headerresponse.copy(headers = response.headers.add("X-Custom", "value"))
// Add multiple headersresponse.copy(headers = response.headers.addAll(Seq( "Cache-Control" -> "no-cache", "X-Request-Id" -> "abc123")))
// Read a headerresponse.headers.get("content-type") // Option[String]response.headers.contains("x-custom") // Boolean
// Remove a headerresponse.copy(headers = response.headers.remove("x-custom"))Headers are normalized with smart casing — content-type becomes Content-Type, common acronyms like API, JWT, CORS are uppercased correctly.
Default Headers
Section titled “Default Headers”Every response includes these headers automatically:
| Header | Value |
|---|---|
Server | Apion |
Cache-Control | no-store, no-cache, must-revalidate, max-age=0 |
Pragma | no-cache |
Expires | 0 |
X-Powered-By | Apion |
Date | RFC 1123 formatted current time |
Configure or override defaults:
Response.configure(Seq( "Server" -> "MyApp", "X-Powered-By" -> "MyApp"))
// Reset to defaultsResponse.resetDefaultHeaders()Cookies
Section titled “Cookies”Set cookies on responses using extension methods:
// Simple cookieresponse.withCookie("session", "abc123")
// Cookie with attributesresponse.withCookie( name = "session", value = "abc123", maxAge = Some(3600), // 1 hour path = Some("/"), secure = true, httpOnly = true, sameSite = Some("Strict"))
// Using a Cookie objectresponse.withCookie(Cookie( name = "session", value = "abc123", maxAge = Some(3600), httpOnly = true))
// Clear a cookieresponse.clearCookie("session")Result Extension Methods
Section titled “Result Extension Methods”Add headers to a Future[Result]:
"Hello".asText.withHeader("X-Custom", "value")
data.asJson.withHeaders( "X-Request-Id" -> requestId, "X-Duration" -> s"${duration}ms")Reading the Body
Section titled “Reading the Body”For testing or inspection:
response.bodyText // String content of the response body