Skip to main content

Respond With Directives

Respond-with directives add headers to HTTP responses produced by inner routes. They are useful for applying cross-cutting response headers such as CORS, caching, or custom application headers.

respondWithHeader​

Unconditionally adds the given header to all responses from the inner route. The new header is prepended to the existing headers -- if a header with the same name already exists, both the new and the existing header will be present in the response.

import org.http4s.Header
import org.typelevel.ci.CIString

val route: Route = respondWithHeader(Header.Raw(CIString("X-Custom"), "value")) {
complete("Response with custom header")
}

respondWithDefaultHeader​

Adds the given header to responses only if a header with the same name is not already present. Existing headers are preserved.

import org.http4s.Header
import org.typelevel.ci.CIString

val route: Route = respondWithDefaultHeader(Header.Raw(CIString("Cache-Control"), "max-age=3600")) {
complete("Response with default cache header")
}

respondWithHeaders​

Unconditionally adds multiple headers to all responses from the inner route. The new headers are prepended to the existing headers -- if headers with the same names already exist, both new and existing headers will be present in the response.

A Seq-based overload and a varargs overload are available:

import org.http4s.Header
import org.typelevel.ci.CIString

val corsHeaders = Seq(
Header.Raw(CIString("Access-Control-Allow-Origin"), "*"),
Header.Raw(CIString("Access-Control-Allow-Methods"), "GET, POST, PUT, DELETE")
)

val route: Route = respondWithHeaders(corsHeaders) {
complete("CORS-enabled response")
}

// Varargs overload
val route2: Route = respondWithHeaders(
Header.Raw(CIString("Access-Control-Allow-Origin"), "*"),
Header.Raw(CIString("Access-Control-Allow-Methods"), "GET, POST, PUT, DELETE")
) {
complete("CORS-enabled response")
}

respondWithDefaultHeaders​

Adds multiple headers to responses, but only those headers whose names are not already present in the response.

A Seq-based overload and a varargs overload are available:

import org.http4s.Header
import org.typelevel.ci.CIString

val defaultHeaders = Seq(
Header.Raw(CIString("X-Frame-Options"), "DENY"),
Header.Raw(CIString("X-Content-Type-Options"), "nosniff")
)

val route: Route = respondWithDefaultHeaders(defaultHeaders) {
complete("Response with security headers")
}

// Varargs overload
val route2: Route = respondWithDefaultHeaders(
Header.Raw(CIString("X-Frame-Options"), "DENY"),
Header.Raw(CIString("X-Content-Type-Options"), "nosniff")
) {
complete("Response with security headers")
}