[Java/Kotlin] Simple&Lightweightなフレームワークのjavalinを動かしてみる

javalinって何?

javalinとは、Java/Kotlin用のシンプルなWebフレームワークです。
定番のHelloWorldは↓のように記述してサーバを起動(HelloWorldクラスの実行)すれば、

//HelloWorld.java
import io.javalin.Javalin;

public class HelloWorld {
    public static void main(String[] args) {
        Javalin app = Javalin.create().start(7000);
        app.get("/", ctx -> ctx.result("Hello World"));
    }
}

簡単に動作を確認することができます。

% curl http://localhost:7000/
Hello World

javalinは、最初はSparkのforkとして作成されたそうですが、
その後すぐにkoa.js(こことかここ参照)の影響を受けて大幅に修正されたようです。
元々javalinはSparkのサブセットとして開発されていましたが、
一気にポピュラーになって機能もSparkと同等になりました。

javalinの特徴

公式サイトにある記述にならって、javalinの特徴をざっと説明します。

  • Simple&Lightweight
    javalinはシンプル。
    新しく学ぶ概念もなく、クラスをextendsすることもインターフェイスを
    implementsする必要もありません。
    また、javalinはJettyにのっている数千行程度のコードであり、とても軽量。

  • Active&Interoperable
    javalinにおいて、メジャーバージョンアップ以外はすべて後方互換性があります。
    そしてinteroperability(相互的な運用性)を考慮して開発されているので、
    アプリケーションはJavaとKotlinどちらも同じように構築されています。

  • Flexible
    javalinはデフォルトで同期モードで動作しますが、
    結果としてFutureを設定した場合には非同期で動かすこともできます。

ではjavalinのセットアップから動作確認までをやってみましょう。

環境

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.12.6
  • Java : 1.8.0_121
  • Gradle : 5.2.1

setup javalin

Gradleのinitタスクで雛形となるプロジェクトを作成します。

% mkdir javalin-example && cd javalin-example
% gradle init --type java-application

build.gradleの記述を、下記のように修正します。

plugins {
    id 'java'
}

repositories {
    jcenter()
}

dependencies {
    implementation 'com.google.guava:guava:27.0.1-jre'

    // add Javalin libs
    compile 'io.javalin:javalin:2.8.0'
    compile "org.slf4j:slf4j-simple:1.7.26"

    testImplementation 'junit:junit:4.12'
}

javalinには簡単にCRUD用コントローラを作成するinterfaceを提供しています。
javalin-example/src/main/java/javalin/exampleに、MyCrudController.javaファイルを作成しましょう。

package javalin.example;

import io.javalin.Context;
import io.javalin.apibuilder.CrudHandler;
import org.jetbrains.annotations.NotNull;

public class MyCrudController implements CrudHandler {
    @Override
    public void create(@NotNull Context ctx) {
        ctx.json("created : " + ctx.body());
    }

    @Override
    public void delete(@NotNull Context ctx, @NotNull String s) {
        ctx.json("deleted : " + s);
    }

    @Override
    public void getAll(@NotNull Context ctx) {
        ctx.json("get All");
    }

    @Override
    public void getOne(@NotNull Context ctx, @NotNull String s) {
        ctx.json("get One : " + s);
    }

    @Override
    public void update(@NotNull Context ctx, @NotNull String s) {
        ctx.json("updated : " + s);
    }
}

CrudHandlerを実装すると、CRUDの各種処理を簡単に実装できます。
今回は手抜きしてCRUDのメッセージを返すだけにします。

そしてサーバの起動やroutes定義を記述する、Main.javaを作成します。

package javalin.example;

import io.javalin.Javalin;
import static io.javalin.apibuilder.ApiBuilder.*;

public class Main {
    public static void main(String[] args) {
        Javalin app = Javalin.create().start(7000);
        app.routes(() -> {
            crud("hello/:hello_id", new MyCrudController());
        });
    }
}

上記のように記述すれば、MyCrudControllerのCRUD処理が適切なパスに関連付けられます。

ではjavalinを起動して動作を確認してみましょう。

objc[51774]: Class JavaLaunchHelper is implemented in both・・・
[main] INFO org.eclipse.jetty.util.log - Logging initialized @497ms to org.eclipse.jetty.util.log.Slf4jLog
[main] INFO io.javalin.Javalin - 
           __                      __ _
          / /____ _ _   __ ____ _ / /(_)____
     __  / // __ `/| | / // __ `// // // __ \
    / /_/ // /_/ / | |/ // /_/ // // // / / /
    \____/ \__,_/  |___/ \__,_//_//_//_/ /_/

        https://javalin.io/documentation

[main] INFO io.javalin.Javalin - Starting Javalin ...
[main] INFO io.javalin.Javalin - Listening on http://localhost:7000/
[main] INFO io.javalin.Javalin - Javalin started in 620ms \o/

下記のように各種APIが動作しているのがわかります。

%curl -X POST http://localhost:7000/hello -d {}
"created : {}"                                                                                           
%curl -X PATCH http://localhost:7000/hello/1 -d {}
"updated : 1"                                                                                            
%curl -X GET http://localhost:7000/hello/1
"get One : 1"                                                                                           
%curl -X GET http://localhost:7000/hello
"get All"
%curl -X DELETE http://localhost:7000/hello/1
"deleted : 1"

まとめ

今回はJavaの軽量フレームワークjavalinを使ってみました。
チュートリアルをみれば
必要そうなことはだいたい書いてあるので、すぐに使い始めることができると思います。