在Spray

时间:2016-01-07 11:20:18

标签: scala spray spray-dsl

我在Spray中有以下代码来解析用户调用的REST服务:

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

2 个答案:

答案 0 :(得分:2)

此处的一个问题是,由于id被声明为optional,因此您的parameter路由会同时处理它的存在和缺席(以及正在处理v0/pets)。

一种方法(我还假设您只想处理get次请求)。

您基本上只是在id路线上声明parameter 不是可选的

val route = get {
  pathPrefix("v0") {
    pathPrefix("pets") {
      pathEnd {
        parameter('id) { id =>
          complete("/v0/pets?id=" + id)
        } ~ complete("/v0/pets")
      } ~
      pathSingleSlash {
        complete("/v0/pets/")
      }
    }
  }
}

另一种方法基本上只是利用了id是一个可选参数的事实,所以你只需在Option上进行模式匹配:

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/")
        }
      }
    }
  }
}

答案 1 :(得分:1)

pathPrefix("v0") {
  pathPrefix("pets") {
    pathEndOrSingleSlash {
      get {
      }
    }
  }
}

匹配http://127.0.0.1/v0/pets?id=1234

这就是为什么

GET /v0/pets?id=1234
 ^   ^   ^  ^
 |___|___|__|____ get  
     |   |  |
     |   |  |
     |   |  |__ pathEndOrSlash
     |   |  
     |   |__ pathPrefix("pets")
     |
     |__ pathPrefix("v0")

您之前需要拦截parameter。尝试

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/")
        }
      }
    }
  }
}