RESTXの紹介

RESTXの概要

1. 概要

このチュートリアルでは、軽量のJava RESTフレームワークRESTXのツアーに参加します。

2. 特徴

RESTXフレームワークを使用すると、RESTful APIを簡単に構築できます。 JSONの提供と使用、クエリとパスのパラメーター、ルーティングとフィルタリングのメカニズム、使用統計、モニタリングなど、RESTフレームワークに期待できるすべてのデフォルトがあります。

RESTXには、簡単なブートストラップのための直感的な管理Webコンソールとコマンドラインインストーラーも付属しています。

また、Apache License 2の下でライセンスされ、開発者のコ​​ミュニティによって維持されています。 RESTXのJavaの最小要件はJDK 7です。

3. 設定

RESTXには、Javaプロジェクトをすばやくブートストラップするのに役立つ便利なシェル/コマンドアプリが付属しています。

先に進むには、まずアプリをインストールする必要があります。 詳細なインストール手順は、hereで入手できます。

4. コアプラグインのインストール

次に、コアプラグインをインストールして、シェル自体からアプリを作成できるようにします。

RESTXシェルで、次のコマンドを実行してみましょう。

shell install

次に、インストールするプラグインを選択するように求められます。 io.restx:restx-core-shellを指す数値を選択する必要があります。 The shell will automatically restart once installation completes.

5. シェルアプリブートストラップ

RESTXシェルを使用すると、新しいアプリをブートストラップすることが非常に便利です。 ウィザードベースのガイドを提供します。

シェルで次のコマンドを実行することから始めます。

app new

このコマンドはウィザードをトリガーします。 次に、デフォルトのオプションを使用するか、要件に従って変更します。

imageimage

pom.xml,を生成することを選択したため、プロジェクトは任意の標準JavaIDEに簡単にインポートできます。

場合によっては、the IDE settingsを微調整する必要があります。

次のステップは、プロジェクトをビルドすることです。

mvn clean install -DskipTests

Once the build is successful we can run the AppServer class as a Java Application from the IDE。 これにより、ポート8080でリッスンする管理コンソールでサーバーが起動します。

http://127.0.0.1:8080/api/@/ui を参照して、基本的なUIを確認できます。

/@/で始まるルートは、RESTXの予約済みパスである管理コンソールに使用されます。

管理コンソールにログインするには、デフォルトのユーザー名「admin」と、アプリの作成時に指定したパスワードを使用できます。

コンソールを試してみる前に、コードを調べて、ウィザードが何を生成したかを理解しましょう。

6. RESTXリソース

ルートは<main_package>.rest.HelloResourceクラスで定義されています。

@Component
@RestxResource
public class HelloResource {
    @GET("/message")
    @RolesAllowed(Roles.HELLO_ROLE)
    public Message sayHello() {
        return new Message().setMessage(String.format("hello %s, it's %s",
          RestxSession.current().getPrincipal().get().getName(),
          DateTime.now().toString("HH:mm:ss")));
    }
}

RESTXがセキュリティとRESTバインディングにデフォルトのJ2EEアノテーションを使用していることはすぐにわかります。 ほとんどの場合、依存性注入に独自の注釈を使用します。

RESTXは、mapping method parameters to the requestの多くの妥当なデフォルトもサポートします。

また、これらの標準アノテーションに加えて、@RestxResourceがあります。これは、RESTXが認識するリソースとして宣言します。

ベースパスはsrc/main/webapp/WEB-INF/web.xml.に追加されます。この場合は/apiなので、適切な認証を前提として、http://localhost:8080/api/messageにGETリクエストを送信できます。

Messageクラスは、RESTXがJSONにシリアル化する単なるJavaBeanです。

ブートストラップによって生成されたHELLO_ROLEを使用して、RolesAllowedアノテーションを指定することにより、ユーザーアクセスを制御します。

7. モジュールクラス

前述のように、RESTXは@NamedなどのJ2EE標準の依存性注入アノテーションを使用し、必要に応じて独自のアノテーションを考案します。おそらく、@Module@Provides.のDaggerフレームワークからヒントを得ます。

これらを使用して、アプリケーションのメインモジュールを作成します。このモジュールは、特に管理者パスワードを定義します。

@Module
public class AppModule {

    @Provides
    public SignatureKey signatureKey() {
        return new SignatureKey("restx-demo -44749418370 restx-demo 801f-4116-48f2-906b"
            .getBytes(Charsets.UTF_8));
    }

    @Provides
    @Named("restx.admin.password")
    public String restxAdminPassword() {
        return "1234";
    }

    @Provides
    public ConfigSupplier appConfigSupplier(ConfigLoader configLoader) {
        return configLoader.fromResource("restx/demo/settings");
    }

    // other provider methods to create components
}

@Module は、Daggerの@ModuleやSpringの@Configuration と同様に、他のコンポーネントを定義できるクラスを定義します。

@Providesは、Daggerの@Provides やSpringの@Beanのように、プログラムでコンポーネントを公開します。

そして最後に、@Namedアノテーションを使用して、生成されたコンポーネントの名前を示します。

AppModuleは、クライアントに送信されるコンテンツの署名に使用されるSignatureKeyも提供します。 たとえば、サンプルアプリのセッションの作成中に、設定されたキーで署名されたCookieが設定されます。

HTTP/1.1 200 OK
...
Set-Cookie: RestxSessionSignature-restx-demo="ySfv8FejvizMMvruGlK3K2hwdb8="; RestxSession-restx-demo="..."
...

詳細については、RESTX’s components factory/dependency injection documentationを確認してください。

8. ランチャークラス

そして最後に、AppServerクラスを使用して、組み込みJettyサーバーで標準のJavaアプリとしてアプリケーションを実行します。

public class AppServer {
    public static final String WEB_INF_LOCATION = "src/main/webapp/WEB-INF/web.xml";
    public static final String WEB_APP_LOCATION = "src/main/webapp";

    public static void main(String[] args) throws Exception {
        int port = Integer.valueOf(Optional.fromNullable(System.getenv("PORT")).or("8080"));
        WebServer server =
            new Jetty8WebServer(WEB_INF_LOCATION, WEB_APP_LOCATION, port, "0.0.0.0");
        System.setProperty("restx.mode", System.getProperty("restx.mode", "dev"));
        System.setProperty("restx.app.package", "restx.demo");
        server.startAndAwait();
    }
}

ここでは、devモードを開発フェーズで使用して、開発フィードバックループを短縮する自動コンパイルなどの機能を有効にします。

アプリをwar(ウェブアーカイブ)ファイルとしてパッケージ化して、スタンドアロンのJ2EEウェブコンテナにデプロイできます。

次のセクションでアプリをテストする方法を見つけましょう。

9. 仕様を使用した統合テスト

RESTXの強力な機能の1つは、「仕様」の概念です。 サンプルspecは次のようになります。

title: should admin say hello
given:
  - time: 2013-08-28T01:18:00.822+02:00
wts:
  - when: |
      GET hello?who=xavier
    then: |
      {"message":"hello xavier, it's 01:18:00"}

テストは、YAMLファイル内のGiven-When-Then構造で記述されます。これは、現在の状態を前提として、特定の要求(when)に対してAPIがどのように応答するか(then)を基本的に定義します。システムの(given)。

src/test/resourcesHelloResourceSpecTestクラスは、上記の仕様で記述されたテストをトリガーします。

@RunWith(RestxSpecTestsRunner.class)
@FindSpecsIn("specs/hello")
public class HelloResourceSpecTest {}

RestxSpecTestsRunnerクラスはcustom JUnit runnerです。 以下を行うためのカスタムJUnitルールが含まれています。

  • 組み込みサーバーをセットアップする

  • システムの状態を準備します(仕様のgivenセクションに従って)

  • 指定されたリクエストを発行し、

  • 期待される応答を確認する

@FindSpecsInアノテーションは、テストを実行する必要があるスペックファイルのパスを指します。

The spec helps to write integration tests and provide examples in the API docs.仕様はmock HTTP requests and record request/response pairsにも役立ちます。

10. 手動テスト

HTTPを介して手動でテストすることもできます。 最初にログインする必要があり、これを行うには、RESTXコンソールで管理者パスワードをハッシュする必要があります。

hash md5 

そして、それを/sessionsエンドポイントに渡すことができます。

curl -b u1 -c u1 -X POST -H "Content-Type: application/json"
  -d '{"principal":{"name":"admin","passwordHash":"1d528266b85cf052803a57288"}}'
  http://localhost:8080/api/sessions

(Windowsユーザーは最初にdownloadカールする必要があることに注意してください。)

そして今、/messageリクエストの一部としてセッションを使用する場合:

curl -b u1 "http://localhost:8080/api/message?who=restx"

次に、次のようなものが得られます。

{"message" : "hello admin, it's 09:56:51"}

11. 管理コンソールの探索

管理コンソールは、アプリを制御するための有用なリソースを提供します。

http://127.0.0.1:8080/admin/@/uiを参照して、主な機能を見てみましょう。

11.1. APIドキュメント

APIドキュメントセクションには、すべてのオプションを含むすべての利用可能なルートがリストされます。

imageimage

そして、個々のルートをクリックして、コンソール自体で試してみることができます。

imageimage

11.2. モニタリング

JVM Metricsセクションには、アクティブなセッション、メモリ使用量、およびスレッドダンプを含むアプリケーションメトリックが表示されます。

imageimage

Application Metricsの下には、デフォルトで監視される要素の主に2つのカテゴリがあります。

  • BUILDは、アプリケーションコンポーネントのインスタンス化に対応します

  • HTTPは、RESTXによって処理されるHTTPリクエストに対応します

11.3. 統計

RESTXを使用すると、ユーザーはアプリケーションで匿名の統計を収集して共有し、RESTXコミュニティに情報を提供できます。 We can easily opt out by excluding the restx-stats-admin module.

統計は、基盤となるOSやJVMバージョンなどを報告します。

imageimage

Because this page shows sensitive information,make sure to review its configuration options

これらとは別に、管理コンソールも役立ちます:

  • サーバーログ(ログ)を確認します

  • 発生したエラーを表示します(エラー)

  • 環境変数を確認します(Config)

12. 承認

RESTX endpoints are secured by default.つまり、エンドポイントの場合:

@GET("/greetings/{who}")
public Message sayHello(String who) {
    return new Message(who);
}

認証なしで呼び出されると、デフォルトで401 が返されます。

エンドポイントを公開するには、メソッドレベルまたはクラスレベルで@PermitAllアノテーションを使用する必要があります。

@PermitAll
@GET("/greetings/{who}")
public Message sayHello(String who) {
    return new Message(who);
}

クラスレベルでは、すべてのメソッドがパブリックであることに注意してください。

さらに、フレームワークでは、@RolesAllowedアノテーションを使用してユーザーロールを指定することもできます。

@RolesAllowed("admin")
@GET("/greetings/{who}")
public Message sayHello(String who) {
    return new Message(who);
}

この注釈により、RESTXは認証されたユーザーに管理者ロールも割り当てられているかどうかを確認します。 管理者の役割を持たない認証済みユーザーがエンドポイントにアクセスしようとすると、アプリケーションは401ではなく403 を返します。

デフォルトでは、ユーザーロールと資格情報はファイルシステムの個別のファイルに保存されます。

したがって、暗号化されたパスワードを持つユーザーIDは、/data/credentials.jsonファイルに保存されます。

{
    "user1": "$2a$10$iZluUbCseDOvKnoe",
    "user2": "$2a$10$oym3Swr7pScdiCXu"
}

また、ユーザーロールは/data/users.jsonファイルで定義されています。

[
    {"name":"user1", "roles": ["hello"]},
    {"name":"user2", "roles": []}
]

サンプルアプリでは、ファイルはFileBasedUserRepositoryクラスを介してAppModuleに読み込まれます。

new FileBasedUserRepository<>(StdUser.class, mapper,
  new StdUser("admin", ImmutableSet. of("*")),
  Paths.get("data/users.json"), Paths.get("data/credentials.json"), true)

StdUserクラスはユーザーオブジェクトを保持します。 カスタムユーザークラスにすることもできますが、JSONにシリアル化できる必要があります。

もちろん、データベースにアクセスするような、別のUserRepository実装を使用することもできます。


13. 結論

このチュートリアルでは、軽量のJavaベースのRESTXフレームワークの概要を説明しました。

フレームワークはまだ開発中であり、それを使用するいくつかのラフなエッジがあるかもしれません。 詳細については、the official documentationを確認してください。

サンプルのブートストラップアプリは、GitHub repositoryで入手できます。