Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to match all paths in Akka HTTP

Most Akka HTTP examples show it is really easy to define Routes using path.

I have the following (slightly simplified) from the introductory example,

val route =
  path("hello") {
    complete(
      HttpEntity(
        ContentTypes.`text/html(UTF-8)`,
        "<h1>Say hello to akka-http</h1>"))
  }

However, the above only works for "/hello" and I want to match all possible paths or URLs, not just "hello". The empty string, "", only matches the root path and "*" matches the literal path "/*". The parameter to path is required and cannot simply be omitted.

like image 762
vossad01 Avatar asked Jan 13 '17 03:01

vossad01


1 Answers

The there are a lot of ways this can be accomplished. I believe the following shows some ways ordered most preferred to least preferred.

Use other types of directives

The simplest solution requires knowing that the Route can be any Directive, not only path directives. Thus, the original example could be modified to achieve the desired results by just by dropping the path completely:

val route =
  complete(
    HttpEntity(
      ContentTypes.`text/html(UTF-8)`,
      "<h1>Say hello to akka-http</h1>"))

Use a different PathMatcher with path

path does not actually take a String as a parameter. path("hello") is actually pathPrefix(_segmentStringToPathMatcher("hello")) after implicit conversion. The desired outcome is possible using different arguments of type PathMatcher.

You can use Remaining which matches everything left.

val route =
  path(Remaining) { _ =>
    complete(
      HttpEntity(
        ContentTypes.`text/html(UTF-8)`,
        "<h1>Say hello to akka-http</h1>"))
  }

Or you can use a regular expression:

val route =
  path(".*".r) { _ =>
    complete(
      HttpEntity(
        ContentTypes.`text/html(UTF-8)`,
        "<h1>Say hello to akka-http</h1>"))
  }

Both of the above make available the match and thus you have the additional ignored lambda argument.

Use pathPrefix("") instead of path("")

According to the documentation for path empty string, "", does in behave a little like a wildcard in that will always match a string. However, path requires an exact match (the entire string be consumed by the match) but the empty string only completely consumes the empty string. Since pathPrefix only requires the beginning of the string to match, not the entire string be consumed, the following works:

val route =
  pathPrefix("") {
    complete(
      HttpEntity(
        ContentTypes.`text/html(UTF-8)`,
        "<h1>Say hello to akka-http</h1>"))
  }
like image 55
vossad01 Avatar answered Sep 28 '22 17:09

vossad01