如何递归处理Akka HTTP路由

如何递归处理Akka HTTP路由,akka,akka-http,Akka,Akka Http,我有一个场景,其中路由包含交替的键/值对段。对的数量未定义,收集这些对的有效方法是什么。例如,路线可能看起来像 /key1/value1/key2/value2/key3/value3 我想要一个与 (key1, value1) -> (key2, value2) -> (key3, value3) 我知道我们可以得到一个路径段列表,并按照上面的方式进行转换。但我要找的是一种能沿着这条路走下去的东西 class EntitiesSpec extends WordSpec with

我有一个场景,其中路由包含交替的键/值对段。对的数量未定义,收集这些对的有效方法是什么。例如,路线可能看起来像

/key1/value1/key2/value2/key3/value3
我想要一个与

(key1, value1) -> (key2, value2) -> (key3, value3)
我知道我们可以得到一个路径段列表,并按照上面的方式进行转换。但我要找的是一种能沿着这条路走下去的东西

class EntitiesSpec extends WordSpec with Matchers with ScalatestRouteTest with Directives {

  def lastSegment:Directive1[String] = path(Segment)
  def intermediate: Directive1[String] = <processing the intermediate>

  val navigate = (intermediate & navigate) ~ lastSegment
  val route = navigate { (param1:String) =>
    complete(param1)
  }

  "this should call the route" should {
    "invoke a route /hello" in {
      Get("/hello/world/hello1/world1/hello3/world3") ~> route ~> check {
        println(responseAs[String])
      }
    }
  }
}

如何定义可以递归地添加数字的指令?非常感谢您的帮助。

不要将路径用于键/值对

问题中描述的方法是一种反模式。在中,键/值配对可以更容易地完成。通过使用该指令,将键/值对转换为
String
元组列表变得非常简单:

//matches a uri of the form: /?key1=value1&key2=value2
val queryStringRoute = 
  parameterMap { params =>
    val linkedPairList : List[(String, String)] = params.toList
  }
不要对指令使用递归

递归指令也是不明智的:

因为返回类型是未来的,所以任何递归都必须是对原始未来的操作。因此,不能忽略原始调用堆栈,递归永远不会进行尾部优化。如果路径足够长,则可能导致递归函数的堆栈溢出

如果必须使用路径

当您除了使用
路径
之外别无选择时,您只需执行一些
字符串
解析:

val pathToKeyValuePairs : Uri.Path => List[(String, String)] =
  (_ : Uri.Path)
    .toString
    .split('/')
    .grouped(2)
    .map(arr => arr(0) -> arr(1))
    .toList
现在可以在
路由中使用此解析器:

val unadvisedRoute = 
  extractRequest { request =>
    val linkedPairList : List[(String, String)] = 
      pathToKeyValuePairs(request.uri.path)
  }
val pathToKeyValuePairs : Uri.Path => List[(String, String)] =
  (_ : Uri.Path)
    .toString
    .split('/')
    .grouped(2)
    .map(arr => arr(0) -> arr(1))
    .toList
val unadvisedRoute = 
  extractRequest { request =>
    val linkedPairList : List[(String, String)] = 
      pathToKeyValuePairs(request.uri.path)
  }