2014-09-23 3 views
1

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

  • //example.com/users < - список всех
  • //example.com/users?age=30 < - все пользователи, которые 30
  • //example.com/ ? пользователей возраст = 30 & имя = John < - все пользователи, которые 30 и называются Джон
  • ...

Я использую 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 
} 

я понял, что я могу получить полную строку запроса из объекта запроса, который является карта [String, Seq [String]]. Но тогда я не знаю, как хорошо проверить, являются ли значения String или что-то еще.

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

ответ

0

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

  1. Использование POST вместо GET: POST /example.com/users "данные" = { ​​"возраст": 25, "имя": "хуг" , ...}
  2. ИЛИ одного парам в ГЭТ: ПОЛУЧИТЬ /example.com/users?filter={"age":25, "имя": "хуг", ...}

На стороне сервера j ust подтвердите свой класс модели или просто передайте один и тот же json в вашем методе findivemongo find.

0

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

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

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

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

для запросов, как это:

/age?from=1&to=10 

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