所以我有一个看起来像这样的路由文件:
GET /myRes controllers.MyController.get(ids: Option[String], elems: Option[String])
一切都很好。用户可以通过以下方式获得东西:
/myRes
/myRes?ids=X
/myRes?elems=Y
/myRes?ids=X&elems=Y
但是,他们也可以通过以下方式查询接口(interface):
/myRes?id=X
这是有问题的,因为在这种情况下,用户得到的结果与他们查询 /myRes
时得到的结果相同,这几乎肯定不是他们预期的结果。这给 API 开发人员造成了很多困惑/错误。是否有一种优雅的方法来捕获传递给 Controller 的不正确/未指定的查询参数并为此类查询返回硬错误?
编辑:将标题更改为更具描述性的内容。我的问题基本上是验证查询参数以捕获传递给 API 的任何无效/不正确的查询参数。
最佳答案
这可以借助像下面这样的宏注释来完成:
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 {
...
}
关于scala - 如何验证 Play Framework 中的可选查询参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39329451/