2016-04-12 30 views
1

Tüm isteklerim için belirli sorgu parametrelerine erişme yoluna sahip olmak istiyorum. Ben virgül erişmek istediğinizListe parametresi olarak sorgu parametresi

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

include ilişkilerin ayrılmış listesi: Bir örnek sorgu gibi bir şey olurdu.


Bildiğim kadarıyla söyler misiniz, aşağıdaki çalışmıyor ve tek dize olarak dahil listeye bakacağız:

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

Bu şu anda yapıyorum nasıl ama ben daha temiz bir yol olduğunu umuyordum.

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

otomatik olarak o içinde include için Seq("friends", "photos") bağlamak istiyorum That:

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

} 

cevap

3

(zaten Oynat tarafından desteklenen) bunu yapmak için uygun yolu, yani sorgu dizesinde tekrarlanan anahtar değerleri kullanmak olacaktır rota. Bu, anahtarlar içinde virgül kullanabilme avantajına sahiptir ve sorgu dizesi parametrelerinin yaygın kullanımıyla tutarlıdır.

Alternatif olarak, virgülle ayrılmış bir listeyi işleyebilen özel bir QueryStringBindable[List[String]] oluşturabilirsiniz. gibi bir şey: O zaman build.sbt içinde PlayKeys.routesImport += "QueryStringBinders._" kullanacağı

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(",")}""" 

     } 
    } 

} 

(veya tam paket adı her neyse) kullanmak. Bir QueryStringBindable kullanmak, bölünmüş mantığı en az boilerplate ile yeniden kullanılabilir hale getirir. Eğer

rotanız yani hem queryString yöntemi ile sorgu dizesi erişebilir http://api.mysite.com/accounts/123?include=friends&include=photos

ve size eylemde:

0

gibi, @mz gibi kullanmak uygun yolu sorgu dizesi anahtar değerlerini tekrar edilir söyledi

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

ve denetleyici içinde:

// 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) 
    } 
aşağıdaki gibi görünecektir