2016-04-12 3 views
1

Я хочу получить доступ к некоторым параметрам запроса для всех моих запросов. Пример запроса будет что-то вроде:Параметр запроса как Список

http://api.mysite.com/accounts/123?include=friends,photos 

Где я хочу, чтобы получить доступ к разделенных запятыми список include отношений.


Насколько я мог бы сказать следующее не работает, и будет выглядеть в списке включают в себя как одну строку:

// routes.txt 
GET /accounts/:id controllers.AccountsController.get(id: Int, include: Seq[String]) 

Это, как я сейчас делаю это , но я надеялся, что есть более чистый способ.

// routes.txt 
GET /accounts/:id controllers.AccountsController.get(id: Int, include: Option[String]) 

// AccountsController.scala 
def get(id: Int, include: Option[String]) = Action { 

    // Convert the option to a set 
    val set = if (include.isDefined) include.get.split(",").toSet else Set() 

} 

ответ

3

Правильный способ сделать это (уже поддерживается Play) будет использовать повторяющиеся ключевые значения в строке запроса, то есть:

http://api.mysite.com/accounts/123?include=friends&include=photos 

Это будет автоматически связывать Seq("friends", "photos") с include в том, что маршрут. Это имеет то преимущество, что можно использовать запятые в ключах и согласуется с общим использованием параметров строки запроса.

Кроме того, вы можете создать пользовательский QueryStringBindable[List[String]], который может обрабатывать список, разделенный запятыми. Что-то вроде:

object QueryStringBinders { 

    implicit def listBinder(key: String)(implicit stringBinder: QueryStringBindable[String]) = { 
     new QueryStringBindable[List[String]] { 
      override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, List[String]]] = 
       stringBinder.bind(key, params).map(_.right.map(_.split(",").toList)) 

      override def unbind(key: String, strings: List[String]): String = 
       s"""$key=${strings.mkString(",")}""" 

     } 
    } 

} 

Тогда вы будете использовать PlayKeys.routesImport += "QueryStringBinders._" в build.sbt использовать его (или что-то полное имя пакета). Использование QueryStringBindable сделает раздельную логику многократной, с минимальным шаблоном.

0

Как, @mz сказал правильный способ использовать повтор ключ-значение в строке запроса, как: http://api.mysite.com/accounts/123?include=friends&include=photos

и в вас действии вы можете получить доступ к строке запроса с queryString методом, а также то

своего маршрута будет выглядеть следующим образом:

GET /accounts/:id controllers.AccountsController.get(id: Int) 

и в контроллере:

// AccountsController.scala 

    def get(id: Int) = Action { request => 

     // the `request.queryString` will give you Map[String, Seq[String]] i.e all they keys and their values 

     val includes = request.queryString.getOrElse("include", Nil) 
    } 
Смежные вопросы