Edg*_*erg 2 scala spray spray-dsl
在这里回答我自己的问题,因为这花了我一天多的时间来弄清楚,这是一个非常简单的问题,我认为其他人可能会遇到.
在使用REST创建RESTful-esk服务时,我希望将具有字母数字id的路由作为路径的一部分进行匹配.这是我最初开始的:
case class APIPagination(val page: Option[Int], val perPage: Option[Int])
get {
pathPrefix("v0" / "things") {
pathEndOrSingleSlash {
parameters('page ? 0, 'perPage ? 10).as(APIPagination) { pagination =>
respondWithMediaType(`application/json`) {
complete("things")
}
}
} ~
path(Segment) { thingStringId =>
pathEnd {
complete(thingStringId)
} ~
pathSuffix("subthings") {
pathEndOrSingleSlash {
complete("subthings")
}
} ~
pathSuffix("othersubthings") {
pathEndOrSingleSlash {
complete("othersubthings")
}
}
}
}
} ~ //more routes...
Run Code Online (Sandbox Code Playgroud)
这没有问题编译,但是当使用scalatest来验证路由结构是否正确时,我很惊讶地发现这种类型的输出:
"ThingServiceTests:"
"Thing Service Routes should not reject:"
- should /v0/things
- should /v0/things/thingId
- should /v0/things/thingId/subthings *** FAILED ***
Request was not handled (RouteTest.scala:64)
- should /v0/things/thingId/othersubthings *** FAILED ***
Request was not handled (RouteTest.scala:64)
Run Code Online (Sandbox Code Playgroud)
我的路线出了什么问题?
我看了很多资源,比如这个SO问题和这篇博文,但似乎找不到任何关于使用字符串Id作为路径结构的顶层部分的信息.在查看这个重要的测试之前,我查看了喷雾scaladoc以及在Path matchers上的文档中击败我的头部(下面重复):
"pathPrefix(Segment)" should {
val test = testFor(pathPrefix(Segment) { echoCaptureAndUnmatchedPath })
"accept [/abc]" in test("abc:")
"accept [/abc/]" in test("abc:/")
"accept [/abc/def]" in test("abc:/def")
"reject [/]" in test()
}
Run Code Online (Sandbox Code Playgroud)
这让我想到了几件事.我应该尝试使用pathPrefix而不是path.所以我改变了我的路线,看起来像这样:
get {
pathPrefix("v0" / "things") {
pathEndOrSingleSlash {
parameters('page ? 0, 'perPage ? 10).as(APIPagination) { pagination =>
respondWithMediaType(`application/json`) {
listThings(pagination)
}
}
} ~
pathPrefix(Segment) { thingStringId =>
pathEnd {
showThing(thingStringId)
} ~
pathPrefix("subthings") {
pathEndOrSingleSlash {
listSubThingsForMasterThing(thingStringId)
}
} ~
pathPrefix("othersubthings") {
pathEndOrSingleSlash {
listOtherSubThingsForMasterThing(thingStringId)
}
}
}
}
} ~
Run Code Online (Sandbox Code Playgroud)
并且很高兴让我的所有测试通过并且路由结构正常工作.然后我更新它以使用Regex匹配器:
pathPrefix(new scala.util.matching.Regex("[a-zA-Z0-9]*")) { thingStringId =>
Run Code Online (Sandbox Code Playgroud)
并决定在SO上发布任何遇到类似问题的人.正如jrudolph在评论中指出的那样,这是因为Segment期望匹配<Segment><PathEnd>而不是在路径中间使用.哪个pathPrefix更有用
| 归档时间: |
|
| 查看次数: |
1972 次 |
| 最近记录: |