LoginSignup
7
8

More than 5 years have passed since last update.

Ratpack を Java の Micro Web Application Framework として使う

Posted at

概要

こちらのSpringOne Platform の参加報告記事を読んでいたら、 Ratpack という Web Application Framework があることを知りましたので、Java の Web アプリケーション開発で使ってみました。

Ratpack とは

Ratpack is a set of Java libraries for building modern HTTP applications.
It provides just enough for writing practical, high performance, apps.
It is built on Java 8, Netty and reactive principles.
(公式サイトより引用)

Java や Groovy で Web アプリケーションを開発できる Micro Web Application Framework だそうです。開発したアプリケーションは fat-jar を作成することで簡単にデプロイできます。

軽く調べてみた限りでは Groovy での開発サンプルが多いようですが、Java でもアプリケーションを開発できるようですので、今回は Java で試してみました。

ちなみに、ratpack という単語について調べてみたところ、あまりよい意味ではありませんでしたRat Pack(Wikipedia 英語版)を見ると、 Frank Sinatra に関係のある語らしいので、それが由来なのかなと思いました。

ライセンス

Apache License 2.0 です。

Google トレンド

ratpack framework で調べると下記のグラフが表示されました。このグラフによると、最近急激に注目が高まっているようです。

ratpack_trend.png


実行環境

Java SE 1.8.0_102
OS Windows 10
Ratpack 1.4.1

依存の追加

依存のダウンロードを始めたところ、結構時間がかかります。
Framework のコア部分で使用されている Netty をはじめ、下記のライブラリが使われているようです。

  1. Guava
  2. Jackson
  3. SLF4J
  4. Javassist
  5. SnakeYAML
dependencies tree
$ gradle dependencies
:dependencies

------------------------------------------------------------
Root project
------------------------------------------------------------

archives - Configuration for archive artifacts.
No dependencies

compile - Dependencies for source set 'main'.
\--- io.ratpack:ratpack-core:1.4.1
     +--- io.netty:netty-codec-http:4.1.4.Final
     |    \--- io.netty:netty-codec:4.1.4.Final
     |         \--- io.netty:netty-transport:4.1.4.Final
     |              +--- io.netty:netty-buffer:4.1.4.Final
     |              |    \--- io.netty:netty-common:4.1.4.Final
     |              \--- io.netty:netty-resolver:4.1.4.Final
     |                   \--- io.netty:netty-common:4.1.4.Final
     +--- io.netty:netty-handler:4.1.4.Final
     |    +--- io.netty:netty-buffer:4.1.4.Final (*)
     |    +--- io.netty:netty-transport:4.1.4.Final (*)
     |    \--- io.netty:netty-codec:4.1.4.Final (*)
     +--- io.netty:netty-transport-native-epoll:4.1.4.Final
     |    +--- io.netty:netty-common:4.1.4.Final
     |    +--- io.netty:netty-buffer:4.1.4.Final (*)
     |    \--- io.netty:netty-transport:4.1.4.Final (*)
     +--- com.google.guava:guava:19.0
     +--- org.slf4j:slf4j-api:1.7.21
     +--- org.reactivestreams:reactive-streams:1.0.0
     +--- com.github.ben-manes.caffeine:caffeine:2.3.1
     +--- org.javassist:javassist:3.19.0-GA
     +--- com.fasterxml.jackson.core:jackson-databind:2.7.5
     |    +--- com.fasterxml.jackson.core:jackson-annotations:2.7.0
     |    \--- com.fasterxml.jackson.core:jackson-core:2.7.5
     +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.7.5
     |    +--- com.fasterxml.jackson.core:jackson-core:2.7.5
     |    \--- org.yaml:snakeyaml:1.15
     +--- com.fasterxml.jackson.datatype:jackson-datatype-guava:2.7.5
     |    +--- com.fasterxml.jackson.core:jackson-databind:2.7.5 (*)
     |    \--- com.fasterxml.jackson.core:jackson-core:2.7.5
     +--- org.yaml:snakeyaml:1.15
     +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.7.5
     |    +--- com.fasterxml.jackson.core:jackson-core:2.7.5
     |    \--- com.fasterxml.jackson.core:jackson-databind:2.7.5 (*)
     \--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.7.5
          +--- com.fasterxml.jackson.core:jackson-core:2.7.5
          \--- com.fasterxml.jackson.core:jackson-databind:2.7.5 (*)

……省略……

(*) - dependencies omitted (listed previously)

build.gradle の修正

この記事を書いている段階では1.4.1が最新でした。

build.gradle
apply plugin: 'application'

sourceCompatibility = 1.8
mainClassName       = "jp.toastkid.ratpack.Main"


repositories {
  mavenCentral()
}

dependencies {
  compile 'io.ratpack:ratpack-core:1.4.1'
  testCompile 'junit:junit:4.12'
}

jar {
  manifest {
    attributes 'Main-Class'   : mainClassName
  }
  destinationDir = projectDir
  from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

サンプルアプリケーションを試す

最初の方に出てくるサンプルはテストパッケージのを使っているので今回はスルーし、4 Launchingのサンプルを試します。

import java.net.URI;

import ratpack.server.RatpackServer;
import ratpack.server.ServerConfig;

public class Main {
    public static void main(final String... args) throws Exception {
        RatpackServer.start(server -> server
                .serverConfig(ServerConfig.embedded().publicAddress(new URI("http://company.org")))
                .registryOf(registry -> registry.add("World!"))
                .handlers(chain -> chain
                  .get(ctx -> ctx.render("Hello " + ctx.get(String.class)))
                  .get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens().get("name") + "!"))
                )
              );
    }
}

起動すると下記の通り出力されます。

起動
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
WARNING: No slf4j logging binding found for Ratpack, there will be no logging output.
WARNING: Please add an slf4j binding, such as slf4j-log4j2, to the classpath.
WARNING: More info may be found here: http://ratpack.io/manual/current/logging.html
Ratpack started (development) for http://localhost:61762

正常系

ブラウザで http://localhost:61762 にアクセスすると、 Hello World! と表示されています。

エラーページ

http://localhost:61762/notfound/page のような適当なパスにアクセスするとエラーページが表示されます。

namepath

http://localhost:61762/toastkid にアクセスすると、表示されるメッセージが Hello toastkid! に変化します。


fat-jar から起動

もちろん fat-jar を作ってそれをサーバ上で動かすこともできます。

fat-jarの作成
$ gradle clean jar
:clean UP-TO-DATE
:compileJava
:processResources UP-TO-DATE
:classes
:jar

BUILD SUCCESSFUL

Total time: 3.544 secs
実行
$ java -jar ratpack_example.jar
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
WARNING: No slf4j logging binding found for Ratpack, there will be no logging output.
WARNING: Please add an slf4j binding, such as slf4j-log4j2, to the classpath.
WARNING: More info may be found here: http://ratpack.io/manual/current/logging.html
Ratpack started (development) for http://localhost:61810

http://localhost:61810 にアクセスすると Hello World! と表示されます。


いろいろ試す

Ratpack を使ってどのようなことができるのか、いろいろ見ていきます。

ポート番号指定

ServerConfigBuilder の port(int) メソッドで指定できます。
ここでポート番号を指定すると、ランダムではなく、必ずこのポートで起動するようになります。

port(int)
RatpackServer.start(server -> server
                .serverConfig(
                        ServerConfig.embedded()
                            .publicAddress(new URI("http://company.org"))
+                           .port(8940)
                            )

GET パラメータ受け取り

GET はそんなに難しくなく、handlers 内に下記を追加するだけで取れます。

GET
context.getRequest().getQueryParams().getOrDefault("paramName", "defaultValue")

もうちょっと長めに取り出すとこのような感じです。

GET
.handlers(chain -> chain
  .get(context -> {
      final String name = context.getRequest().getQueryParams().getOrDefault("name", "Guest");
      context.render(String.format("Hello %s.", name));
  })
)

サーバを起動し、ブラウザでアクセスしてみます。上記のコードの場合、パラメータがない時はHello Guest.、ある時は名前が表示されます。

POST パラメータ受け取り

POST のパラメータを受け取る場合は下記のようにします。

POST
.post("wc/result", context -> {
    final Promise<Form> form = context.parse(Form.class);
    form.then(f -> {
        final String param= f.get("paramName");
        context.render(String.format("paramName=%s.", param));
    }

エラー表示(Development)

Development 環境ではエラーメッセージが専用の画面で、StackTrace と併せて表示されます。

例えば存在しないパスにアクセスした場合、下記のようなエラー画面が出ます。

スクリーンショット (2).png

ContentType の指定

デフォルトだと text/plain で描画されます。HTML で描画する場合は指定が必要です。

最初は下記のように2行に分けて書いていました。

ContentTypeを指定してrender
context.getResponse().contentType(MediaType.TEXT_HTML);
context.render(template.make(renderArgs).toString());

どうやら下記でよいらしいです。

ContentTypeを指定してrender
context.getResponse().send(MediaType.TEXT_HTML, template.make(renderArgs).toString());

リソースフォルダの指定

ドキュメントを見ても全然わからなかったので、GitHubのサンプルプロジェクト を見て真似してみたらようやくわかりました。

baseDir を指定

設定を追加します。

baseDirを指定
server.serverConfig(ServerConfig.embedded()
    .baseDir(BaseDir.find())
)

リソースフォルダと同じ階層に .ratpack ファイルを配置

.ratpack ファイルはただのマーカーなので空ファイルでよいです。Windows では . で始まるファイル名を作ろうとするとエラーになりますので、 IDE から、もしくは touch コマンド(Git Bash 等を入れているなら)で作ります。

例えば、下記のようなフォルダ構成で、public 以下のリソースを参照したいとします。

ファイルツリー
└─src
    ├─main
    │  └─resources
    │      └─public
    │          ├─images
    │          ├─javascripts
    │          │  ├─d3
    │          │  └─d3-cloud
    │          └─stylesheets

その場合、resources フォルダの直下に .ratpack ファイルを置いてください。

ファイルツリー
└─src
    ├─main
    │  └─resources
    │      ├─public
    │      └─.ratpack

.ratpack ファイルの配置が適切でないと、

Could not find marker file '.ratpack' via context class loader

というエラーメッセージが出力され、アプリケーションの起動に失敗します。

リソースを指定

JavaScript や CSS や画像ファイルといったリソースを使いたい場合、コード上で下記のように指定します。

chain.prefix(
    "アプリケーションで参照するときのパス",
    nested -> nested.fileSystem("マーカーファイルの位置から見た、追加したいリソースへのパス", Chain::files)
)

1ファイル単位ないし1フォルダ単位での指定が可能です。下記の場合だと、 public を指定して images と javascripts と stylesheets をまとめてリンクすることはできません。

chain.prefixでフォルダ単位でリンク
.handlers(chain -> chain
    .prefix("public/images",      nested -> nested.fileSystem("public/images",      Chain::files))
    .prefix("public/javascripts", nested -> nested.fileSystem("public/javascripts", Chain::files))
    .prefix("public/stylesheets", nested -> nested.fileSystem("public/stylesheets", Chain::files))

HTML テンプレート

今回は Groovy のテンプレートエンジンを使ってみました。groovy-all の依存を追加するだけで使えます。

build.gradleに依存を追加
dependencies {
+  compile 'org.codehaus.groovy:groovy-all:2.4.5'
}
Templateの用意
final Template template = new StreamingTemplateEngine()
    .createTemplate(Paths.get(PATH_TO_TEMPLATE).toFile());
パラメータのバインディング
final Map<String, String> renderArgs = new HashMap<>();
......
final String html = template.make(renderArgs).toString();

例えば、<title>${title}</title> というテンプレートを用意した場合、上記の renderArgs"title", "タイトル" というペアを追加しておくと、 html<title>タイトル</title> という文字列が入ります。

Groovy のテンプレートエンジンの詳細については下記のリンク先をご参照ください。

  1. Groovy のテンプレートエンジン
  2. Template engines

Word Cloud

いつものように Word Cloud アプリケーションを作ってみました。ソースコードは ratpack_word_cloud(GitHub) に置いてありますので、興味がございましたらご覧ください。


リンク

Ratpack

  1. Official site
  2. GitHub repository
  3. GitHubのサンプルプロジェクト
  4. Learning Ratpack(英語書籍)……無料サンプルあり
  5. Ratpackについて(前編)
  6. Ratpackについて(後編)
  7. Ratpackについて(延長戦)
  8. Building Web Apps in Ratpack

Groovy テンプレートエンジン

  1. Groovy のテンプレートエンジン
  2. Template engines
  3. Groovyのヒアドキュメント

Groovy での Ratpack 開発

  1. [Groovy]RatpackでシンプルなWEBアプリケーションを開発する -インストール&Hello World-
  2. [Groovy]RatpackでシンプルなWEBアプリケーションを開発する -基本的なHTTPルーティング-
  3. [Groovy]RatpackでシンプルなWEBアプリケーションを開発する -JSONとJSONPを扱う-
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8