Skip to content

Misc Directives

Johannes Rudolph edited this page · 7 revisions

. . .

Deprecation Note

This documentation is for release 0.9.0 (from 03/2012), which is built against Scala 2.9.1 and Akka 1.3.1 (see Requirements for more information). Most likely, this is not the place you want to look for information. Please turn to the main spray site at for more information about other available versions.

. . .

In addition to the directives described in the other chapters spray also offers a number of simpler directives that are collectively documented on this page.

The host Directive

The host directive filters on the contents of the requests Host header. There are three variants:

  • host(String) simply filters on an exact match of the hostname
  • host(String => Boolean) lets the given predicate function decide whether to accept or reject the request
  • host(Regex) performs a match against the given regex and extracts the matched string

If the regex contains a capturing group the extraction is limited to the string matched by the group. The regex is not allowed to contain more than one capturing group. If the host filter does not match the request is rejected, which triggers a 404 Not found error response if no subsequent route successfully handles the request.


host("") {
  ... // only responds to requests on host "")

host("(www1|www2)".r) { server =>
  ... // 'server' contains either "www1" or "www2"

The validate Directive

The validate directive allows you to hook a simple validation check into the routing structure. If the check fails a ValidationRejection rejection is created, which, by default, triggers a 400 Bad Request error response with a custom error message. You can use the validate directive for example to perform checks on previously extracted values as demonstrated in this example:

parameter('age as[Int]) { age =>
  validate(18 >= age && age <= 99, "age must be between 18 and 99") {

The respondWith... Directives

spray has a number of directives that let you change particular properties of the HttpResponse created by an inner route:

  • respondWithStatus
  • respondWithHeader / respondWithHeaders
  • respondWithContentType
  • respondWithMediaType

These directives don't extract anything and always pass on the request unchanged to their inner routes. They only apply their logic to successful responses from inner routes, not rejections.

For example, to change the response status code of a response do:

respondWithStatus(StatusCodes.Accepted) {
  ... // inner route


respondWithStatus(202) {
  ... // inner route

To add a given HTTP header to the response do:

respondWithHeader(CustomHeader("X-Powered-By", "spray 0.8.0")) {

To change the media type of a response:

respondWithMediaType(`application/x-www-form-urlencoded`) {

The jsonpWithParameter Directive

This rather special directive implements JSONP support. If a query parameter with the given name is present in the request and the directives inner route returns content with content-type application/json the response content is wrapped with a call to a Javascript function having the name of query parameters value. Additionally the content-type is changed from application/json to application/javascript in these cases.

This is how you use it:

path("hello") {
  jsonpWithParameter("callback") {
      // some route producing `application/json` content
      _.complete(HttpContent(`application/json`, """{ "key": "some value" }"""))

If this route is hit by request to /path the response will have the content

{ "key": "some value" }

and Content-Type: application/json. However, if this route is hit by request to /path?callback=parseResponse the response will have the content

parseResponse({ "key": "some value" })

and Content-Type: application/javascript.

The implementation of the jsonpWithParameter is a good example of how compact custom directives may be implemented, here it is:

import MediaTypes._
import marshalling.DefaultUnmarshallers._

def jsonpWithParameter(parameterName: String) = transformRequestContext { ctx =>
  ctx.withHttpResponseTransformed {
    _.withContentTransformed { content =>
      (ctx.request.queryParams.get(parameterName), content.contentType) match {
        case (Some(wrapper), ContentType(`application/json`, charset)) =>
          HttpContent(ContentType(`application/javascript`, charset),
                  wrapper + '(' +[String].right.get + ')')
        case _ => content
Something went wrong with that request. Please try again.