parameters

The parameters directive filters on the existence of several query parameters and extract their values.

Signature

def parameters(param: <ParamDef[T]>): Directive1[T]
def parameters(params: <ParamDef[T_i]>*): Directive[T_0 :: ... T_i ... :: HNil]
def parameters(params: <ParamDef[T_0]> :: ... <ParamDef[T_i]> ... :: HNil): Directive[T_0 :: ... T_i ... :: HNil]

The signature shown is simplified and written in pseudo-syntax, the real signature uses magnets. [1] The type <ParamDef> doesn’t really exist but consists of the syntactic variants as shown in the description and the examples.

[1]See The Magnet Pattern for an explanation of magnet-based overloading.

Description

Query parameters can be either extracted as a String or can be converted to another type. The parameter name can be supplied either as a String or as a Symbol. Parameter extraction can be modified to mark a query parameter as required or optional or to filter requests where a parameter has a certain value:

"color"
extract value of parameter “color” as String
"color".?
extract optional value of parameter “color” as Option[String]
"color" ? "red"
extract optional value of parameter “color” as String with default value "red"
"color" ! "blue"
require value of parameter “color” to be "blue" and extract nothing
"amount".as[Int]
extract value of parameter “amount” as Int, you need a matching Deserializer in scope for that to work (see also Unmarshalling)
"amount".as(deserializer)
extract value of parameter “amount” with an explicit Deserializer

You can use Case Class Extraction to group several extracted values together into a case-class instance.

Requests missing a required parameter or parameter value will be rejected with an appropriate rejection.

There’s also a singular version, parameter. Form fields can be handled in a similar way, see formFields. If you want unified handling for both query parameters and form fields, see anyParams.

Examples

Required parameter

val route =
  parameters('color, 'backgroundColor) { (color, backgroundColor) =>
    complete(s"The color is '$color' and the background is '$backgroundColor'")
  }

Get("/?color=blue&backgroundColor=red") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is 'red'"
}
Get("/?color=blue") ~> sealRoute(route) ~> check {
  status === StatusCodes.NotFound
  responseAs[String] === "Request is missing required query parameter 'backgroundColor'"
}

Optional parameter

val route =
  parameters('color, 'backgroundColor.?) { (color, backgroundColor) =>
    val backgroundStr = backgroundColor.getOrElse("<undefined>")
    complete(s"The color is '$color' and the background is '$backgroundStr'")
  }

Get("/?color=blue&backgroundColor=red") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is 'red'"
}
Get("/?color=blue") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is '<undefined>'"
}
val route =
  parameters('color, 'backgroundColor ? "white") { (color, backgroundColor) =>
    complete(s"The color is '$color' and the background is '$backgroundColor'")
  }

Get("/?color=blue&backgroundColor=red") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is 'red'"
}
Get("/?color=blue") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is 'white'"
}

Optional parameter with default value

val route =
  parameters('color, 'backgroundColor ? "white") { (color, backgroundColor) =>
    complete(s"The color is '$color' and the background is '$backgroundColor'")
  }

Get("/?color=blue&backgroundColor=red") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is 'red'"
}
Get("/?color=blue") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and the background is 'white'"
}

Parameter with required value

val route =
  parameters('color, 'action ! "true") { (color) =>
    complete(s"The color is '$color'.")
  }

Get("/?color=blue&action=true") ~> route ~> check {
  responseAs[String] === "The color is 'blue'."
}

Get("/?color=blue&action=false") ~> sealRoute(route) ~> check {
  status === StatusCodes.NotFound
  responseAs[String] === "The requested resource could not be found."
}

Deserialized parameter

val route =
  parameters('color, 'count.as[Int]) { (color, count) =>
    complete(s"The color is '$color' and you have $count of it.")
  }

Get("/?color=blue&count=42") ~> route ~> check {
  responseAs[String] === "The color is 'blue' and you have 42 of it."
}

Get("/?color=blue&count=blub") ~> sealRoute(route) ~> check {
  status === StatusCodes.BadRequest
  responseAs[String] === "The query parameter 'count' was malformed:\n'blub' is not a valid 32-bit integer value"
}