scala - 如何验证 Play Framework 中的可选查询参数?

标签 scala playframework

所以我有一个看起来像这样的路由文件:

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/

相关文章:

java - 为什么声明 "Driver not found: [org.postgresql.Driver]"与 postgresql 9.3-1102.jdbc41 依赖关系?

java - Play 2 : Difference between appDependencies and libraryDependencies?

scala - SBT 项目中的条件设置

scala - 我如何获得一个 Spark 数据帧来打印它的解释计划到一个字符串

scala - 如何在 Scala 中获取当前时间戳作为没有空格的字符串?

scala - 如何从graphx中的元组构建图并在之后标记节点?

java - Scala IDE (Eclipse) 作为 Scala 应用程序运行

java - 使用静态参数玩框架反向路由

playframework - Play Framework 作为 WebSocket 客户端

java - 使用 Play 框架的移动应用程序的不同 View