Как сопоставить все пути в Akka HTTP

Большинство примеров Akka HTTP показывают, что очень легко определить Routes с помощью path.

У меня есть следующее (слегка упрощенное) из вводный пример,

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

Однако приведенное выше работает только для «/ hello», и я хочу сопоставить все возможные пути или URL-адреса, а не только «hello». Пустая строка "" соответствует только корневому пути, а "*" соответствует буквальному пути "/*". Параметр path является обязательным и не может быть просто опущен.


person vossad01    schedule 13.01.2017    source источник


Ответы (1)


Есть много способов, которыми это может быть достигнуто. Я считаю, что следующее показывает некоторые способы, упорядоченные от наиболее предпочтительного к наименее предпочтительному.

Используйте другие типы директив

Самое простое решение требует знания того, что Route может быть любым Директива, а не только директивы пути. Таким образом, исходный пример можно изменить для достижения желаемых результатов, просто полностью отбросив path:

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

Используйте другой PathMatcher с path

path на самом деле не принимает String в качестве параметра. path("hello") на самом деле pathPrefix(_segmentStringToPathMatcher("hello")) после неявного преобразования. Желаемый результат возможен при использовании различных аргументов типа PathMatcher.

Вы можете использовать Remaining, который соответствует всему оставшемуся.

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

Или вы можете использовать регулярное выражение:

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

Оба вышеприведенных варианта делают доступным совпадение, и, таким образом, у вас есть дополнительный игнорируемый лямбда-аргумент.

Используйте pathPrefix("") вместо path("")

Согласно документация для path пустой строки, "", ведет себя немного как подстановочный знак, который всегда будет соответствовать строке. Однако path требует точного совпадения (для соответствия используется вся строка), но пустая строка полностью использует только пустую строку. Поскольку pathPrefix требует совпадения только начала строки, а не всей строки, работает следующее:

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