Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在akka http中,通过路径匹配器从uri路径提取两个段值的惯用方法是什么?_Scala_Akka Http - Fatal编程技术网

Scala 在akka http中,通过路径匹配器从uri路径提取两个段值的惯用方法是什么?

Scala 在akka http中,通过路径匹配器从uri路径提取两个段值的惯用方法是什么?,scala,akka-http,Scala,Akka Http,我尝试构建一个akka http路由,从端点api/提取两个值,以便方便地访问域对象Foo()和Bar()。该域如下所示: final case class Foo(foo: String) object Foo { def apply(value: String): Try[Foo] = Try { if (value.length == 3) new Foo(value) else throw new IllegalA

我尝试构建一个akka http路由,从端点
api/
提取两个值,以便方便地访问域对象
Foo()
Bar()
。该域如下所示:

  final case class Foo(foo: String)

  object Foo {
    def apply(value: String): Try[Foo] = Try {
      if (value.length == 3)
        new Foo(value)
      else
        throw new IllegalArgumentException(s"Foo value $value invalid.")
    }
  }

  final case class Bar(bar: String)

  object Bar {
    def apply(value: String): Try[Bar] = Try {
      if (value.length == 4)
        new Bar(value)
      else
        throw new IllegalArgumentException(s"Bar value $value invalid.")
    }
  }
由于我找不到任何好的实践示例,到目前为止,我提出了:

  val fooBarPM: PathMatcher1[Option[(Foo, Bar)]] =
    Segments.map(as => Foo.apply(as.head).toOption.flatMap(foo => Bar.apply(as(1)).toOption.map(bar => (foo, bar) )))

  private def fooBarPath(pm: PathMatcher1[Option[(Foo, Bar)]])
                        (handler: (Foo, Bar) => Route) = path(pm) {
      case None => complete("Invalid foo/bar.")
      case Some((a, b)) => handler(a, b)
    }
  
  val route2: Route =
    pathPrefix("api") {
      fooBarPath(fooBarPM) { (foo, bar) =>
        complete(s"Foo Bar ok: $foo, $bar")
      }
    }

这似乎在大多数有效和无效情况下都能正常工作,除了抛出了
IndexOutOfBoundsException
api/aaa
之外。我怀疑这是一个异常上下文,不知怎么地被忽略了,但也怀疑是否有更好的或惯用的方法。

以下代码不存在由
as(1)
引起的
索引自动边界异常问题

case类Foo(Foo:String)
案例类别栏(栏:字符串)
val fooBarPath:Directive[(Foo,Bar)]=路径前缀(段/段).tflatMap{
如果foo.length==3&&bar.length==4=>tprovide(foo(foo),bar(bar))则为案例(foo,bar)
案例=>reject.toDirective[(Foo,Bar)]
}
val路由:路由=路径前缀(“api”){
fooBarPath{case(foo,bar)=>
完成(s“获得$foo和$bar”)
}
}
使用
tflatMap
转换为正确的值,
(Foo,Bar)
,或
拒绝
传入请求的指令不符合条件


您还可以使用
t过滤器
/
tmap
的组合将过滤/拒绝逻辑与映射逻辑隔离开来。

您尝试过类似的方法吗?您将在以下函数中使用
段?
进行可选路径和验证