2012-07-07 8 views
6

Ich implementiere eine Web-API mit dem Scala 2.0.2 Play Framework. Ich möchte eine Anzahl von Get-Parametern extrahieren und validieren. Und dazu benutze ich eine "Spielform", die es mir ermöglicht, optionale Felder zu definieren.Wie Standardwerte optionale Felder in Play-Rahmenformen definieren?

Problem: Für diese optionalen Felder muss ich einen Standardwert definieren, wenn der Parameter nicht übergeben wird. Der Code soll korrekt diese drei Anwendungsfälle analysieren:?

  • /test top = abc (Fehler, abc keine ganze Zahl ist)
  • /test top = 123 (gültig sind, top 123)
  • /Test (gültig, Top-42 (Standardwert))

ich habe mit dem folgenden Code kommen:

def test = Action { 
    implicit request => 

    case class CData(top:Int) 

    val p = Form(
    mapping(
     "top" -> optional(number) 
    )((top) => CData($top.getOrElse(42))) ((cdata:CData) => Some(Some(cdata.top))) 
).bindFromRequest() 

    Ok("all done.") 
} 

Der Code funktioniert, aber es ist definitiv nicht elegant. Es gibt viele Kesselplatten, nur um einen Standardwert für einen fehlenden Anforderungsparameter einzurichten.

Kann jemand eine sauberere und mehr coincise Lösung vorschlagen?

Antwort

8

Dies ist ein Router-Job, um Abfragezeichenfolgenparameter zu validieren. Definieren Sie einfach Ihre Parameter in der Datei routes:

GET /test controllers.Application.test(top: Int ?= 42) 

Und fügen top als Parameter an Ihrem Controller-Methode:

def test(top: Int) = Action { 
    // Use top here 
    val data = CData(top) 
} 

Dann spielen für Sie alle Validierung Arbeit tun. Beachten Sie, wie der Standardwert unter Verwendung der Syntax angegeben wird.

Sie sollten Formulare nur für POST-Anfragen verwenden.

Update:

Wenn Sie manuell Parameter überprüfen, dann könnten Sie Helper-Methode definieren:

def getQueryParam(key: String, default: String)(implicit request: RequestHeader) = 
    request.queryString.get(key).flatMap(_.headOption).getOrElse(default) 

Und es in Ihrem Controller-Methoden verwenden:

def test = Action { implicit request => 
    val top = getQueryParam("top", "42") 
    ... 

Aber Dadurch verlieren Sie die Typprüfung. Natürlich können Sie Helfer für jeden Typ definieren, d. H. getIntParam, getStringParam und so weiter, aber Play enthält bereits eine sichere Router-Implementierung, die entwickelt wurde, um solche Probleme zu lösen. Ich rate Ihnen, den Routing-Mechanismus anstelle der manuellen Überprüfung zu verwenden.

+0

Dies ist die vorgeschlagene Lösung funktioniert gut. Der einzige Nachteil dieser Lösung besteht leider darin, dass sie mit einer großen Anzahl von Standardparametern nicht gut skaliert. Wenn Sie einen Webdienst/eine Webanwendung erstellen, die die Filterung von Listen unterstützen muss, kann die Sichtbarkeit aller Standardparameter in der Route die Lesbarkeit und die Robustheit des Codes beeinträchtigen.In allen anderen Szenarien ist dies in der Tat die bevorzugte Lösung – natbusa

+1

Antwort aktualisiert mit einer Hilfsmethode-Implementierung, die Sie nützlich finden können. – lambdas

+1

Ich habe eine Erweiterung des Play-Frameworks vorgeschlagen, um einen Code-basierten Ansatz für Standardparameter zu programmieren. Siehe https://github.com/playframework/Play20/pull/381 – natbusa

12

in Play 2,1

 
val p = Form(
    mapping(
     "top" -> default(number,42) 
    )(CData.apply)(CData.unapply) 
).bindFromRequest() 

wird tun, was Sie wollen.

Verwandte Themen