2016-09-05 25 views
2

所以我有一个路由文件看起来是这样的:如何验证Play Framework中的可选查询参数?

GET  /myRes     controllers.MyController.get(ids: Option[String], elems: Option[String]) 

一切都很好。用户可以通过做得到的东西:

/myRes 
/myRes?ids=X 
/myRes?elems=Y 
/myRes?ids=X&elems=Y 

然而,它们还可以通过执行查询的接口:

/myRes?id=X 

这是有问题的,因为在这种情况下,用户得到的结果,如果同他们询问/myRes,这几乎肯定不是他们预期的结果。这对API的开发人员造成了很多混淆/错误。有没有一种优雅的方式来捕获传递给控制器​​的不正确/未指定的查询参数,并返回此类查询的硬错误?

编辑:将标题更改为更具描述性的内容。我的问题基本上是验证查询参数,以捕获传递给API的任何查询参数,这些参数是无效的/正确的。

回答

0

我通常把它传递这样的get方法

GET /getSomething  Controllers.Application.getData() 

GET /getSomething/:id   Controllers.Application.getData(id:Integer) 

GET /getSomething/:id/:name   Controllers.Application.getData(id:Integer, name :String) 
+0

感谢您的回复。但是,这与设置所需的参数基本相同。这也适用于查询参数,但不是我想要做的。没有一个查询参数是必需的,我不想指定每个可能的查询参数组合 - 这不能超过2-3个参数。 –

+0

我改变了标题,希望让问题更清楚。 –

0

它可以与宏注释类似以下的帮助来完成:

import scala.reflect.macros.whitebox.Context 
import scala.language.experimental.macros 
import scala.annotation.StaticAnnotation 
import scala.annotation.compileTimeOnly 
import play.api.mvc._ 

@compileTimeOnly("respond 400 bad request in case of unexpected params") 
class StrictParams extends StaticAnnotation { 
    def macroTransform(annottees: Any*): Any = macro StrictParamsMacro.impl 
} 

object StrictParamsMacro { 
    def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 
    import c.universe._ 
    annottees.map(_.tree).toList match { 
     case q"def $name(..$params) = $action { ..$body }" :: Nil => 
     val supportedParamNames = params.map(ab => ab.name.toString).toSet 
     c.Expr[Any](
      q"""def $name(..$params) = { req: Request[_] => 
      val unsupportedParams = req.queryString.keySet -- $supportedParamNames 
      if (unsupportedParams.nonEmpty) { 
       BadRequest(unsupportedParams.mkString("Unsupported Params: ", ", ", "")) 
      } else { 
       $body 
      } 
      }""" 
     ) 
    } 
    } 
} 

然后你就可以注释动作方法像这样:

@StrictParams 
def get(ids: Option[String], elems: Option[String]) = Action { 
    ... 
} 
+0

非常有趣。将尝试这个尽快。 –

+0

嗯,似乎没有工作。当我们尝试这个时,我们会在编译步骤中得到一个“[error] /*/app/controllers/MyController.scala:88:在出现意外的参数的情况下响应400错误的请求”。我们错过了什么吗? –

+0

宏观天堂需要编译。将以下设置添加到您的项目 - 宏库和使用它的项目。 '''addCompilerPlugin(“org.scalamacros”%“paradise”%2.1.0“cross CrossVersion.full)''' – thirstycrow