Scala Play ReactiveMongo - 任意查询参数列表

时间:2014-09-23 09:52:01

标签: scala playframework reactivemongo play-reactivemongo

我正在尝试为REST API提供任意过滤器,以从MongoDB中获取文档列表。 例如

  • // example.com/users< - list all
  • // example.com/users?age=30< - 所有30岁的用户
  • // example.com/users?age=30&name=John< - 所有30岁并称为John的用户
  • ...

我正在使用Play-ReactiveMongo并仅处理JSONCollection对象。

所以在我的路线中我放了

GET   /users        controllers.Users.list(id: Option[String], name: Option[String], age: Option[Int])

但是有两个问题,首先我需要一个很长的可选参数列表,然后在我的控制器中我需要在所有这些参数上使用模式匹配来检查它们是否为空,还构建了我用来过滤我的集合的选择器。

var filters = JsObject(Nil)
name match {
  case Some(x) => filters += ("name" -> JsString(x))
  case None => None
}

我意识到我可以从请求对象中获取完整的查询字符串,这是一个Map [String,Seq [String]]。但后来我不知道检查值是String还是其他东西的好方法。

还有另一种更好,更惯用的方式来做我想做的事吗?

2 个答案:

答案 0 :(得分:0)

可能的解决办法是:

  1. 使用POST而不是GET: POST /example.com/users “data”= {“age”:25,“name”:“xyz”,...}
  2. 或GET中的单个参数: 获取 /example.com/users?filter={"age":25,"name“:”xyz“,...}
  3. 在服务器端,只需针对您的模型类进行验证,或者只是在您的reactivemongo find方法中传递相同的json。

答案 1 :(得分:0)

也许请求绑定器可以帮助您根据不同的请求参数创建复杂的对象。

https://www.playframework.com/documentation/2.5.x/ScalaRequestBinders#QueryStringBindable

例如,您可以构建类似这样的内容(来自文档):

case class AgeRange(from: Int, to: Int)

对于这样的请求:

/age?from=1&to=10

现在,您可以将这些属性更改为Option,并根据手头的值创建一个创建reactivemongo查询的函数。