2016-04-12 18 views
1

すべてのリクエストに対して特定のクエリパラメータにアクセスする方法が必要です。リストをパラメータとしてクエリする

私は include関係のカンマ区切りリストへのアクセスを取得したい
http://api.mysite.com/accounts/123?include=friends,photos 

:クエリの例は次のようなものになるだろう。

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

これは私が現在、それをやっている方法です。私の知る限り言うことができるよう、次のように動作しませんし、1つの文字列として含まれ、リストを見ていきます


しかし、私はよりクリーンな方法があることを望んでいた。

// 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

それを行うための適切な方法は、(すでにプレイでサポートされている)つまり、クエリ文字列で繰り返しキー値を使用することです:

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

自動的にその中includeSeq("friends", "photos")を結合しますルート。これには、キー内でカンマを使用できるという利点があり、クエリ文字列パラメータの一般的な使用法と一致しています。

また、コンマ区切りリストを処理できるカスタム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(",")}""" 

     } 
    } 

} 

次に、あなたがそれ(または任意の完全修飾パッケージ名がある)を使用するbuild.sbt内PlayKeys.routesImport += "QueryStringBinders._"を使用します。 QueryStringBindableを使用すると、分割ロジックを最小限の定型文で再利用できるようになります。あなたのルートhttp://api.mysite.com/accounts/123?include=friends&include=photos

、あなたのアクションで、あなたが

すなわち、同様queryString方法でクエリ文字列にアクセスすることができます。@mzが使用する適切な方法は次のようにクエリ文字列でKey-Valueを繰り返していると述べた

0

として、

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) 
    } 
関連する問題