8

私の Web アプリケーションは、外部システムからトリガーされます。アプリの 1 つの要求パスを呼び出しますが、要求の種類ごとに異なるクエリ パラメーターを使用します。

パラメータの 1 つは、実行する内容を定義する「アクション」です。残りのパラメーターは「アクション」に依存します。

したがって、次のようなリクエストパラメーターを取得できます。

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

プレイ用にルートファイルで同様にエンコードできるようにしたいので、クエリパラメーターベースのルーティングと、可能な限り他のパラメーターの検証を行います。

私が代わりに持っているのは、多くのオプションのパラメーターを使用して、これらすべての可能性に対応する 1 つのルーティングです。ディスパッチとパラメーターの検証を行うために、アクション処理は大きなパターン マッチから始まります。

SO をグーグルで調べてチェックすると、パラメータが何らかの形でリクエスト パスにエンコードされている多くのサンプルがポップアップ表示されたので、複数のパスが同じアクションにルーティングされますが、1 つのパスが異なるアクションにルーティングされるようにしたいと思います。

私の同僚の 1 人は、「アクション」パラメーターに基づいてリダイレクトするだけの「ディスパッチャー」アクションを 1 つ持つことができると言いました。現在のソリューションよりも少し構造化されていますが、次のアクションに選択的に渡す必要があるオプションのパラメーターの長いリストがなくなるわけではないため、さらに優れたソリューションを知っていることを願っています:-)

ところで、私のアプリを呼び出す外部システムは別の会社によって開発されており、私はこの設計に影響を与えていないため、アプリのトリガー方法を変更することはできません。

4

2 に答える 2

6

おそらく、単一のディスパッチャ アクションが最適であり、ルートですべてのオプション パラメータを指定する必要はありません。が常に存在する場合action、それが本当に必要な唯一のものです。

GET  /someRoute      controller.dispatcher(action: String)

次に、アクション メソッドでアクセスrequest.queryStringして、他の任意のパラメーターを取得できます。

于 2013-03-28T17:13:38.073 に答える
3

注: 私は経験豊富な Scala 開発者ではないため、提示されたスニペットを最適化できる可能性があります...重要なのは、それらが有効で機能していることです。

そう...

ファイル内のすべてのオプション パラメータを宣言する必要はありませんroutes。これは型パラメータの検証の近道であり、最良の選択は「他の会社」にあなたが用意した API を使用するよう説得することです... とにかく、そのような可能性がない場合は、必要に応じ要求を処理することもできます。

一般に、この場所ではディスパッチャーのroutesアプローチが正しいようです。幸いなことに、リクエストから直接フェッチできるため、アクション/メソッド間ですべてのオプションのパラメーターを宣言して渡す必要はありません。$_GET['action']PHP では、Java バージョンの Play 2 コントローラー -DynamicFormクラス -と比較できます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 に答える