PlayのWebCommandsの使い方

Playのドキュメントを見るときに、公式サイトに行かなくても手元で http://localhost:9000/@documentation というURLにアクセスすればドキュメントサイトが見えるということはご存知でしょうか?

これにはWebCommandsという仕組みで動いていて、ドキュメントのほかにもEvolutionsの実行ページの表示などにも使われています。 普通のアプリケーションを作る分には必要ないですが、開発用のライブラリにWeb UIをつけたいときなどは便利です。

例えば、/@hello, /@hello/:name というパスにアクセスすると反応するWebCommandは次のような具合です。

package controllers

import javax.inject.{Provider, Singleton, Inject}

import play.api._
import play.api.inject.{Binding, Module}
import play.api.mvc._
import play.core.{HandleWebCommandSupport, WebCommands}


// 処理本体
class HelloWebCommandHandler extends HandleWebCommandSupport {
  def handleWebCommand(request: play.api.mvc.RequestHeader, buildLink: play.core.BuildLink, path: java.io.File): Option[play.api.mvc.Result] = {
    val pathPattern = """/@hello/([a-zA-Z0-9_]+)""".r
    request.path match {
      case """/@hello""" => Some(Results.Ok("Hello!"))
      case pathPattern(name) => Some(Results.Ok("Hello, " + name + "!"))
      case _ => None
    }
  }
}

// 以下DIのためのお決まりのコード
@Singleton
class HelloWebCommand @Inject() (webCommand: WebCommands) {
  webCommand.addHandler(new HelloWebCommandHandler())
}

class HelloWebCommandModule extends Module {
  override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = {
    Seq(bind[HelloWebCommand].toSelf.eagerly)
  }
}

DIのbindのためのコードが多くて目がやられますが、HelloWebCommandHandlerというのが処理本体です。 簡単ですね。パスにマッチしたらなにか結果をOptionにくるんで返せばいいわけです。 あとはモジュールをapplication.confで登録すれば動きます。

play.modules.enabled += "controllers.HelloWebCommandModule"

以上、scalamatsuri前の小ネタでした。