Javalinを使用したRESTマイクロサービスの作成
1. 前書き
2. 依存関係の追加
3. Javalinのセットアップ
Javalinを使用すると、基本的なアプリケーションを簡単にセットアップできます。 まず、メインクラスを定義し、単純な「HelloWorld」アプリケーションを設定することから始めます。
基本パッケージにJavalinApp.javaという名前の新しいファイルを作成しましょう。
このファイル内で、mainメソッドを作成し、次を追加して基本的なアプリケーションをセットアップします。
Javalin app = Javalin.create()
.port(7000)
.start();
app.get("/hello", ctx -> ctx.html("Hello, Javalin!"));
Javalinの新しいインスタンスを作成し、ポート7000でリッスンさせてから、アプリケーションを起動します。
また、/helloエンドポイントでGETリクエストをリッスンする最初のエンドポイントを設定しています。
このアプリケーションを実行し、http://localhost:7000/helloにアクセスして結果を確認しましょう。
4. UserControllerの作成
「HelloWorld」の例はトピックを紹介するのに最適ですが、実際のアプリケーションには役立ちません。 ここで、Javalinのより現実的なユースケースを見てみましょう。
まず、作業しているオブジェクトのモデルを作成する必要があります。 まず、ルートプロジェクトの下にuserというパッケージを作成します。
次に、新しいUserクラスを追加します。
public class User {
public final int id;
public final String name;
// constructors
}
また、データアクセスオブジェクト(DAO)をセットアップする必要があります。 この例では、メモリ内オブジェクトを使用してユーザーを保存します。
パッケージ化されたuserにUserDao.java:という新しいクラスを作成します
class UserDao {
private List users = Arrays.asList(
new User(0, "Steve Rogers"),
new User(1, "Tony Stark"),
new User(2, "Carol Danvers")
);
private static UserDao userDao = null;
private UserDao() {
}
static UserDao instance() {
if (userDao == null) {
userDao = new UserDao();
}
return userDao;
}
Optional getUserById(int id) {
return users.stream()
.filter(u -> u.id == id)
.findAny();
}
Iterable getAllUsernames() {
return users.stream()
.map(user -> user.name)
.collect(Collectors.toList());
}
}
DAOをシングルトンとして実装すると、例で使用しやすくなります。 また、必要に応じて、メインクラスの静的メンバーとして宣言するか、Guiceなどのライブラリからの依存性注入を使用することもできます。
最後に、コントローラークラスを作成します。 Javalinを使用すると、ルートハンドラを宣言するときに非常に柔軟に対応できるため、これはルートハンドラを定義する1つの方法にすぎません。
userパッケージにUserController.javaという新しいクラスを作成します。
public class UserController {
public static Handler fetchAllUsernames = ctx -> {
UserDao dao = UserDao.instance();
Iterable allUsers = dao.getAllUsernames();
ctx.json(allUsers);
};
public static Handler fetchById = ctx -> {
int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id")));
UserDao dao = UserDao.instance();
User user = dao.getUserById(id);
if (user == null) {
ctx.html("Not Found");
} else {
ctx.json(user);
}
};
}
ハンドラーを静的として宣言することにより、コントローラー自体が状態を保持しないようにします。 ただし、より複雑なアプリケーションでは、リクエスト間に状態を保存したい場合があります。その場合、静的修飾子を削除する必要があります。
また、静的メソッドでは単体テストが難しくなるため、そのレベルのテストが必要な場合は、非静的メソッドを使用する必要があります。
5. ルートの追加
モデルからデータを取得する方法は複数あります。 最後のステップは、RESTエンドポイントを介してこのデータを公開することです。 メインアプリケーションに2つの新しいルートを登録する必要があります。
それらをメインのアプリケーションクラスに追加しましょう。
app.get("/users", UserController.fetchAllUsernames);
app.get("/users/:id", UserController.fetchById);
アプリケーションをコンパイルして実行した後、これらの新しいエンドポイントのそれぞれにリクエストを作成できます。 http://localhost:7000/users willを呼び出すと、すべてのユーザーが一覧表示され、http://localhost:7000/users/0 willを呼び出すと、IDが0の単一のユーザーJSONオブジェクトが取得されます。 これで、Userデータを取得できるマイクロサービスができました。
6. ルートの延長
データの取得は、ほとんどのマイクロサービスの重要なタスクです。
ただし、データストアにデータを保存できる必要もあります。 Javalinは、サービスの構築に必要なパスハンドラーの完全なセットを提供します。
上記のGETの例を見ましたが、PATCH, POST, DELETE, とPUTも可能です。
また、Jacksonを依存関係として含めると、JSON要求本文をモデルクラスに自動的に解析できます。 例えば:
app.post("/") { ctx ->
User user = ctx.bodyAsClass(User.class);
}
これにより、リクエスト本文からJSONUserオブジェクトを取得し、それをUserモデルオブジェクトに変換できます。
7. 結論
これらの手法をすべて組み合わせて、マイクロサービスを作成できます。
この記事では、Javalinをセットアップして簡単なアプリケーションを構築する方法を説明しました。 また、さまざまなHTTPメソッドタイプを使用して、クライアントがサービスと対話できるようにする方法についても説明しました。
Javalinの使用方法のより高度な例については、必ずdocumentationを確認してください。
また、いつものように、コードはover on GitHubで見つけることができます。