Scala Play框架下基于查询参数的路由

Scala Play框架下基于查询参数的路由,scala,playframework-2.0,Scala,Playframework 2.0,我的web应用程序将从外部系统触发。它将调用我的应用程序的一个请求路径,但对不同类型的请求使用不同的查询参数 其中一个参数是定义要做什么的“动作”。其余参数取决于“操作” 因此,我可以获得如下请求参数: action=sayHello&user=Joe action=newUser&name=Joe&address=xxx action=resetPassword ... 我希望能够在播放的routes文件中对其进行类似的编码,以便它执行基于查询参数的路由以及尽可能多的

我的web应用程序将从外部系统触发。它将调用我的应用程序的一个请求路径,但对不同类型的请求使用不同的查询参数

其中一个参数是定义要做什么的“动作”。其余参数取决于“操作”

因此,我可以获得如下请求参数:

action=sayHello&user=Joe
action=newUser&name=Joe&address=xxx
action=resetPassword
...
我希望能够在播放的routes文件中对其进行类似的编码,以便它执行基于查询参数的路由以及尽可能多的其他参数验证

取而代之的是,我为所有这些可能性提供了一个路由,并提供了大量可选参数。操作处理从一个大的模式匹配开始,以执行分派和参数验证

通过谷歌搜索和检查,弹出了大量的示例,其中参数以某种方式编码在请求路径中,因此多个路径被路由到同一个操作,但我希望相反:一个路径路由到不同的操作

我的一位同事说,我们可以有一个“dispatcher”操作,它将根据“action”参数重定向。它将比当前解决方案更结构化,但它不会消除一长串可选参数,这些参数应选择性地传递给下一个操作,因此我希望您知道一个更好的解决方案:-)


顺便说一句,调用我的应用程序的外部系统是由另一家公司开发的,我对该设计没有影响,因此无法更改触发我的应用程序的方式。

单调度器操作可能是一种方法,您不需要在路由中指定所有可选参数。如果
action
始终存在,那么这就是您真正需要的唯一方法

GET  /someRoute      controller.dispatcher(action: String)
然后在您的操作方法中,您可以访问
request.queryString
,以获取任何其他可选参数。

注意:我不是有经验的Scala开发人员,因此可能可以优化呈现的代码段。。。对你来说重要的是,它们有效且有效

所以…

您不需要在
routes
文件中声明每个可选参数。这是验证类型param的一个很好的捷径,最好的选择是说服“其他公司”使用您准备的API。。。无论如何,如果您没有这种可能性,您也可以根据需要处理他们的请求

一般来说:dispatcher方法在这里似乎是正确的,幸运的是,您不需要在
路由中声明所有可选参数,并在操作/方法之间传递它,因为它们可以直接从请求中获取。在PHP中,它可以与
$\u GET['action']
和Java版本的Play 2 controller-
DynamicForm
class-
form().bindFromRequest.GET(“action”)
进行比较

假设您有一条路线:

GET     /dispatcher      controllers.Application.dispatcher
在这种情况下,您的dispatcher操作(和其他方法)可以如下所示:

def dispatcher = Action { implicit request =>
    request.queryString.get("action").flatMap(_.headOption).getOrElse("invalid") match {
      case "sayHello" => sayHelloMethod
      case "newUser"  => newUserMethod
      case _          => BadRequest("Action not allowed!")
    }
}

// http://localhost:9000/dispatcher?action=sayHello&name=John
def sayHelloMethod(implicit request: RequestHeader) = {
  val name = request.queryString.get("name").flatMap(_.headOption).getOrElse("")
  Ok("Hello " + name )
}

// http://localhost:9000/dispatcher?action=newUser&name=John+Doe&address=john@doe.com
def newUserMethod(implicit request: RequestHeader) = {
  val name = request.queryString.get("name").flatMap(_.headOption).getOrElse("")
  val address = request.queryString.get("address").flatMap(_.headOption).getOrElse("")
  Ok("We are creating new user " + name + " with address " + address)
}

当然,您需要“手动”验证传入的类型和值,尤其是当操作将在数据库上运行时,无论如何,您现在已经解决了问题的最大部分。

在您回答问题后,差不多2年过去了。在最新的play framework中有更好的解决方案吗?@Ikrom,我认为更好的解决方案类似于公认的答案,但使用选项params:GET/someRoute controller.dispatcher(操作:option[String])