I'm trying to implement a REST API using the akka-http low-level API. I need to match a request for paths containing resource ids, for instance, "/users/12", where the 12 is the id of the user.
I'm looking for something along these lines:
case HttpRequest(GET, Uri.Path("/users/$asInt(id)"), _, _, _) =>
// id available as a variable
The "$asInt(id)" is a made up syntax, I'm using it just to describe what I want to do.
I can easily find examples of how to do this with the high level API using routes and directives, but I can't find anything with the low-level API. Is this possible with the low-level API?
My team has found a nice solution to this:
/** matches to "/{head}/{tail}" uri path, where tail is another path */
object / {
def unapply(path: Path): Option[(String, Path)] = path match {
case Slash(Segment(element, tail)) => Some(element -> tail)
case _ => None
}
}
/** matches to last element of the path ("/{last}") */
object /! {
def unapply(path: Path): Option[String] = path match {
case Slash(Segment(element, Empty)) => Some(element)
case _ => None
}
}
An example usage (where the expect path is "/event/${eventType}")
val requestHandler: HttpRequest => Future[String] = {
case HttpRequest(POST, uri, _, entity, _) =>
uri.path match {
case /("event", /!(eventType)) =>
case _ =>
}
case _ =>
}
More complex scenarios can be handled by chaining calls to /
, ending with a call to /!
.