Scala Spray中restapi的路径解析
我在Spray中有以下代码来解析用户调用的REST服务:Scala Spray中restapi的路径解析,scala,spray,spray-dsl,Scala,Spray,Spray Dsl,我在Spray中有以下代码来解析用户调用的REST服务: val route = { pathPrefix("v0") { pathPrefix("pets") { pathEndOrSingleSlash { pathEnd { get { complete("/v0/pets") } } ~ get { complete("/v0/pet
val route = {
pathPrefix("v0") {
pathPrefix("pets") {
pathEndOrSingleSlash {
pathEnd {
get {
complete("/v0/pets")
}
} ~
get {
complete("/v0/pets/")
}
} ~
parameters('id ?) {
id =>
get {
complete("/v0/pets?id=" + id)
}
}
}
}
}
问题在于,它的行为并不像预期的那样。
我期待代码中出现以下行为:
http://127.0.0.1/v0/pets => /v0/pets
http://127.0.0.1/v0/pets/ => /v0/pets/
http://127.0.0.1/v0/pets?id=1234 = > /v0/pets?id=Some(1234)
但是,我得到了以下查询结果:
http://127.0.0.1/v0/pets => /v0/pets
http://127.0.0.1/v0/pets/ => /v0/pets
http://127.0.0.1/v0/pets?id=1234 => /v0/pets
火柴
这就是为什么
GET /v0/pets?id=1234
^ ^ ^ ^
|___|___|__|____ get
| | |
| | |
| | |__ pathEndOrSlash
| |
| |__ pathPrefix("pets")
|
|__ pathPrefix("v0")
您需要先截取参数
。试一试
val route = {
pathPrefix("v0") {
pathPrefix("pets") {
parameters('id ?) {
id =>
get {
complete("/v0/pets?id=" + id)
}
} ~
pathEndOrSingleSlash {
pathEnd {
get {
complete("/v0/pets")
}
} ~
get {
complete("/v0/pets/")
}
}
}
}
}
火柴
这就是为什么
GET /v0/pets?id=1234
^ ^ ^ ^
|___|___|__|____ get
| | |
| | |
| | |__ pathEndOrSlash
| |
| |__ pathPrefix("pets")
|
|__ pathPrefix("v0")
您需要先截取参数
。试一试
val route = {
pathPrefix("v0") {
pathPrefix("pets") {
parameters('id ?) {
id =>
get {
complete("/v0/pets?id=" + id)
}
} ~
pathEndOrSingleSlash {
pathEnd {
get {
complete("/v0/pets")
}
} ~
get {
complete("/v0/pets/")
}
}
}
}
}
这里的一个问题是,由于
id
被声明为可选
,因此您的参数
将处理它的存在和不存在(即处理v0/pets
)
一种方法(我还假设您只想处理get
请求)
基本上,您只需在参数上声明id
非可选:
val route = get {
pathPrefix("v0") {
pathPrefix("pets") {
pathEnd {
parameter('id) { id =>
complete("/v0/pets?id=" + id)
} ~ complete("/v0/pets")
} ~
pathSingleSlash {
complete("/v0/pets/")
}
}
}
}
另一种方法基本上就是利用id
是可选参数这一事实,因此您只需在选项上进行模式匹配即可:
val route = {
pathPrefix("v0") {
pathPrefix("pets") {
pathEnd {
get {
parameters('id ?) { id =>
id match {
case Some(id) => complete("/v0/pets?id=" + id)
case None => complete("/v0/pets")
}
}
}
} ~
pathSingleSlash {
get {
complete("/v0/pets/")
}
}
}
}
}
这里的一个问题是,由于id
被声明为可选
,因此您的参数
将处理它的存在和不存在(即处理v0/pets
)
一种方法(我还假设您只想处理get
请求)
基本上,您只需在参数上声明id
非可选:
val route = get {
pathPrefix("v0") {
pathPrefix("pets") {
pathEnd {
parameter('id) { id =>
complete("/v0/pets?id=" + id)
} ~ complete("/v0/pets")
} ~
pathSingleSlash {
complete("/v0/pets/")
}
}
}
}
另一种方法基本上就是利用id
是可选参数这一事实,因此您只需在选项上进行模式匹配即可:
val route = {
pathPrefix("v0") {
pathPrefix("pets") {
pathEnd {
get {
parameters('id ?) { id =>
id match {
case Some(id) => complete("/v0/pets?id=" + id)
case None => complete("/v0/pets")
}
}
}
} ~
pathSingleSlash {
get {
complete("/v0/pets/")
}
}
}
}
}
感谢@gabriele petronella的回复。但对于您建议的解决方案,最后两条路径永远不会执行。它们都只是通过第一个路径执行,并以/v0/pets/?id=none的形式打印输出。哦,是的,我的错,id的可选性使得它无论如何都要进入第一个路径。mfirry的解决方案是可行的。感谢@gabriele petronella的回复。但对于您建议的解决方案,最后两条路径永远不会执行。它们都只是通过第一个路径执行,并以/v0/pets/?id=none的形式打印输出。哦,是的,我的错,id的可选性使得它无论如何都要进入第一个路径。梅弗里的解决方案是可行的。