3

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?

nsantos
  • 568
  • 1
  • 5
  • 15

2 Answers2

2

I found a post in the Akka user list saying that the low-level API does not support this type of path segment extraction:

https://groups.google.com/forum/#!topic/akka-user/ucXP7rjUbyE/discussion

The alternatives are either to use the routing API or to parse the path string ourselves.

nsantos
  • 568
  • 1
  • 5
  • 15
1

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 /!.

tjheslin1
  • 1,378
  • 6
  • 19
  • 36