Bootiqueの紹介

Bootiqueの概要

1. 概要

Bootiqueは、次世代のスケーラブルなマイクロサービスを構築することを目的とした非常に軽量なオープンソースのcontainer-lessJVMフレームワークです。 組み込みのJettyサーバー上に構築され、jax-rsRESTハンドラーを完全にサポートします。

この記事では、Bootiqueを使用して簡単なWebアプリケーションを構築する方法を示します。

2. Mavenの依存関係

次の依存関係をpom.xml:に追加して、Bootiqueの使用を開始しましょう


    io.bootique.jersey
    bootique-jersey
    compile


    io.bootique
    bootique-test
    test

ただし、Bootiqueでは、いくつかのBOM (“Bill of Material”)インポートを宣言する必要もあります。 そのため、次の<dependencyManagement>セクションをpom.xml:に追加する必要があります


    
        
            io.bootique.bom
            bootique-bom
            0.23
            pom
            import
        
    

Bootiqueの最新バージョンはCentral Maven Repositoryで利用できます。

実行可能なjarを作成するために、Bootiquemaven-shade-pluginに依存しています。 そのため、以下の構成も追加する必要があります。


    
        
            org.apache.maven.plugins
            maven-shade-plugin
        
    

3. アプリケーションの開始

Bootiqueアプリケーションを起動する最も簡単な方法は、mainメソッドからBootiqueexec()メソッドを呼び出すことです。

public class App {
    public static void main(String[] args) {
        Bootique.app(args)
          .autoLoadModules()
          .exec();
    }
}

However, this won’t start the embedded server.上記のコードを実行すると、次のログが表示されます。

NAME
      com.example.bootique.App

OPTIONS
      -c yaml_location, --config=yaml_location
           Specifies YAML config location, which can be a file path
           or a URL.

      -h, --help
           Prints this message.

      -H, --help-config
           Prints information about application modules and their
           configuration options.

      -s, --server
           Starts Jetty server.

これらは、Bootiqueにあらかじめバンドルされている利用可能なプログラム引数に他なりません。

名前は一目瞭然です。したがって、サーバーを起動するには、–sまたは–server引数を渡す必要があり、サーバーはdefault port 8080で稼働します。

4. モジュール

Bootiqueアプリケーションは、「モジュール」のコレクションで作成されます。 Bootiqueの用語“A module is a Java library that contains some code”では、すべてのサービスをモジュールとして扱うことを意味します。 依存性注入にGoogle Guiceを使用します。

それがどのように機能するかを確認するために、1つのインターフェースを作成しましょう。

public interface HelloService {
    boolean save();
}

次に、実装を作成する必要があります。

public class HelloServiceImpl implements HelloService {

    @Override
    public boolean save() {
        return true;
    }
}

モジュールをロードする方法は2つあります。 1つはGuiceModuleインターフェースを使用する方法で、もう1つはBootiqueBQModuleProviderauto-loadingとも呼ばれる)を使用する方法です。

4.1. Guiceモジュール

ここでは、GuiceModuleインターフェースを使用してインスタンスをバインドできます。

public class ModuleBinder implements Module {

    @Override
    public void configure(Binder binder) {
        binder
          .bind(HelloService.class)
          .to(HelloServiceImpl.class);
    }
}

モジュールを定義したら、このカスタムモジュールをBootiqueインスタンスにマップする必要があります。

Bootique
  .app(args)
    .module(module)
    .module(ModuleBinder.class)
  .autoLoadModules()
  .exec();

4.2. BQModuleProvider(自動読み込み)

ここで行う必要があるのは、以前に作成したモジュールバインダーをBQModuleProviderで定義することだけです。

public class ModuleProvider implements BQModuleProvider {

    @Override
    public Module module() {
        return new ModuleBinder();
    }
}

この手法の利点は、モジュール情報をBootiqueインスタンスにマッピングする必要がないことです。

/resources/META-INF/services/io.bootique.BQModuleProviderにファイルを作成し、パッケージ名を含むModuleProviderのフルネームを書き込むだけで、残りはBootiqueが処理します。

com.example.bootique.module.ModuleProvider

これで、@Injectアノテーションを使用して、実行時にサービスインスタンスを使用できます。

@Inject
HelloService helloService;

ここで注意すべき重要な点の1つは、Bootique独自のDIメカニズムを使用しているため、サービスインスタンスをバインドするためにGuice @ImplementedByアノテーションを使用する必要がないことです。

5. RESTエンドポイント

JAX-RSAPIを使用してRESTエンドポイントを作成するのは簡単です。

@Path("/")
public class IndexController {

    @GET
    public String index() {
        return "Hello, example!";
    }

    @POST
    public String save() {
        return "Data Saved!";
    }
}

エンドポイントをBootique自身のJerseyインスタンスにマップするには、JerseyModuleを定義する必要があります。

Module module = binder -> JerseyModule
  .extend(binder)
  .addResource(IndexController.class);

6. 設定

YAMLベースのプロパティファイルで組み込みまたはカスタムの構成情報を提供できます。

たとえば、カスタムポートでアプリケーションを起動し、デフォルトのURIコンテキスト「hello」を追加する場合、次のYAML設定を使用できます。

jetty:
    context: /hello
    connector:
        port: 10001

ここで、アプリケーションの起動時に、configパラメーターでこのファイルの場所を指定する必要があります。

--config=/home/example/bootique/config.yml

7. ロギング

すぐに使用できるBootiqueには、bootique-logbackモジュールが付属しています。 このモジュールを使用するには、pom.xmlに次の依存関係を追加する必要があります。


    io.bootique.logback
    bootique-logback

このモジュールにはBootLoggerインターフェースが付属しており、オーバーライドしてカスタムロギングを実装できます。

Bootique.app(args)
  .module(module)
  .module(ModuleBinder.class)
    .bootLogger( new BootLogger() {
      @Override
      public void trace( Supplier args ) {
          // ...
      }
      @Override
      public void stdout( String args ) {
          // ...
      }
      @Override
      public void stderr( String args, Throwable thw ) {
          // ...
      }
      @Override
      public void stderr( String args ) {
          // ...
      }
}).autoLoadModules().exec();

また、config.yamlファイルでロギング構成情報を定義できます。

log:
    level: warn
    appenders:
    - type: file
      logFormat: '%c{20}: %m%n'
      file: /path/to/logging/dir/logger.log

8. テスト

テスト用に、Bootiqueにはbootique-testモジュールが付属しています。 Bootiqueアプリケーションをテストする方法は2つあります。

最初のアプローチは、すべてのテストケースをメインのテストスレッドで実行する‘foreground'アプローチです。

もう1つは、テストケースを分離されたスレッドプールで実行する‘background'アプローチです。

「フォアグラウンド」環境は、BQTestFactoryを使用して初期化できます。

@Rule
public BQTestFactory bqTestFactory = new BQTestFactory();

「バックグラウンド」環境は、BQDaemonTestFactoryを使用して初期化できます。

@Rule
public BQDaemonTestFactory bqDaemonTestFactory = new BQDaemonTestFactory();

環境ファクトリーの準備ができたら、簡単なテストケースを作成してサービスをテストできます。

@Test
public void givenService_expectBoolen() {
    BQRuntime runtime = bqTestFactory
      .app("--server").autoLoadModules()
      .createRuntime();
    HelloService service = runtime.getInstance( HelloService.class );

    assertEquals( true, service.save() );
}

9. 結論

この記事では、Bootiqueのコアモジュールを使用してアプリケーションを構築する方法を示しました。 bootique-jooqbootique-kotlinbootique-jobなどの他のいくつかのBootiqueモジュールが利用可能です。 使用可能なモジュールの完全なリストは、使用可能なhereです。

いつものように、完全なソースコードは利用可能ですover on GitHub.