问题描述
如何验证 PathMatcher
中的 akka-http 路径段?
我想拒绝请求(而不是简单地将其标记为 Unmatched
)。
我想要实现的是返回 400 Bad request 如果 SegmentAsUserId
将段标记为无效:
path(SegmentAsUserId) { implicit userId =>
concat(
get {
handleGet()
},post {
handlePost()
}
)
}
我现在找到的唯一方法是在 PathMatcher1
中抛出异常:
object SegmentAsUserId extends PathMatcher1[String] {
override def apply(path: Path): PathMatcher.Matching[Tuple1[String]] = path match {
case Path.Segment(segment,tail) =>
if (ObjectId.isValid(segment))
Matched(tail,Tuple1(segment))
else
throw InvalidUserIdException(segment)
case _ => Unmatched
}
}
case class FindByIdRequest(id: String) {
require(ObjectId.isValid(id),"The id " + id + " is invalid")
}
path(Segment).as(FindByIdRequest) { implicit userId =>
// ...
}
我知道可以使用指令(拒绝)。但是有路径匹配的机制吗?
更新:
解决方法
我不确定 PathMatchers
是否是您的用例所需要的。来自 Akka 官方 The PathMatcher DSL:
PathMatcher mini-DSL 用于匹配传入的 URL 并从中提取值。它在路径指令中使用。
它不用于检查这些值的有效性。因此,我认为这不是您所需要的。
有一个很好的例子说明了如何使用 PathMatcher
:
val matcher: PathMatcher1[Option[Int]] =
"foo" / "bar" / "X" ~ IntNumber.? / ("edit" | "create")
val route: Route =
path(matcher) { i: Option[Int] =>
complete(s"Matched X${i.getOrElse("")}")
}
为了实现检查验证,请考虑以下路线:
var user = "none"
object ObjectId {
def isValid(s: String): Boolean = s.startsWith("a")
}
val complexRoute: Route = path(Segment) { userId =>
if (ObjectId.isValid(userId)) {
get {
complete(StatusCodes.OK,s"userId is: $user")
} ~
post {
user = userId
complete(StatusCodes.OK)
}
} else {
complete(StatusCodes.BadRequest,s"userId $userId is not supported.")
}
}