Scala Play ReactiveMongo — Произвольный список параметров запроса

Я пытаюсь поддерживать произвольные фильтры для REST API, который извлекает список документов из MongoDB. Например

  • //example.com/users ‹ — список всех
  • //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]]. Но тогда я не знаю хорошего способа проверить, являются ли значения строковыми или чем-то еще.

Есть ли другой лучший и идиоматический способ делать то, что я хочу?


person Henry    schedule 23.09.2014    source источник


Ответы (2)


Возможным решением может быть:

  1. Используйте POST вместо GET: POST /example.com/users "data"={"age":25, "name":"xyz", ... }
  2. ИЛИ один параметр в GET: GET /example.com/users?filter={"age":25, "name":"xyz", ... }

На стороне сервера просто проверьте свой класс модели ИЛИ просто передайте тот же json в свой метод поиска реактивного монго.

person Roshan Sharma    schedule 18.12.2014

Возможно, связыватели запросов помогут вам создавать сложные объекты из различных параметров запроса.

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

Например, вы можете создать что-то вроде этого (из документации):

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

для таких запросов:

/age?from=1&to=10

Теперь вы можете изменить эти атрибуты на Option и создать функцию, которая создает запрос reactivemongo на основе имеющихся значений.

person rethab    schedule 12.06.2016