8

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

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

所以我可以得到这样的请求参数:

action=sayHello&user=Joe
action=newUser&name=Joe&address=xxx
action=resetPassword
...

我希望能够在路由文件中对其进行类似的编码以供播放,以便它执行基于查询参数的路由并尽可能多地验证其他参数。

相反,我拥有的是一个路由,用于所有这些可能性,并带有大量可选参数。它的动作处理从一个大的模式匹配开始,以进行调度和参数验证。

谷歌搜索和检查 SO 只是弹出了大量样本,其中参数以某种方式在请求路径中编码,因此多个路径被路由到相同的操作,但我想要相反:一个路径路由到不同的操作。

我的一位同事说我们可以有一个“调度程序”操作,它只会根据“操作”参数进行重定向。它会比当前的解决方案更有条理,但它不会消除应该有选择地传递给下一个操作的一长串可选参数,所以我希望有人知道一个更好的解决方案:-)

顺便说一句,调用我的应用程序的外部系统是由另一家公司开发的,我对这个设计没有影响,所以改变我的应用程序的触发方式不是一个选择。

4

2 回答 2

6

单个调度程序操作可能是要走的路,您不需要在路由中指定所有可选参数。如果action总是在那里,那么这就是您真正需要的唯一一个。

GET  /someRoute      controller.dispatcher(action: String)

然后在您的操作方法中,您可以访问request.queryString以获取任何其他可选参数。

于 2013-03-28T17:13:38.073 回答
3

注意:我不是经验丰富的 Scala 开发人员,所以也许可以优化呈现的片段......对你来说重要的是它们是有效的并且可以工作。

所以...

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

一般来说:调度程序方法似乎在这个地方是正确的,幸运的是你不需要在中声明所有可选参数routes并在动作/方法之间传递它,因为它们可以直接从请求中获取。在 PHP 中,它可以与$_GET['action']Play 2 控制器 -DynamicForm类 -的 Java 版本进行比较form().bindFromRequest.get("action")

假设您有一条路线:

GET     /dispatcher      controllers.Application.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)
}

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

于 2013-03-28T17:38:50.707 回答