最近、Javaの入門書でQuarkusについて書きましたが、とても魅力的なフレームワークです。みなさんも使ってみませんか?
ただ、クリスマスイブなので、固いコードを書くのはヤメにしました。
この投稿には、ソースコードはほとんどありません。Quarkusを使うと、最近、はやりのマイクロサービスというものを、簡単に始められることを、なんとかコトバだけで伝えたいと思います。
マイクロサービスって?
行き詰まりを感じるモノシリックなシステムを改めて、マイクロサービスで作ろうというのが、大きなトレンドになりました。これから数年のうちに、日本でも大きな変化が出てくるのだろうと思います。
ところで、そのマイクロサービスって?
基本は、RESTfulなウェブサービスです。
これは改めて説明するまでもないと思いますが、宛先URLに向かって、GETやPOSTなどのアクションでパラメータを送り付けると、何か返答を返すサービスです。
URLとアクション、パラメータの組み合わせは無限にあるので、さまざまな応答をプログラムでき、バリエーションは無限です。また、Java以外の言語でも相乗りできるので、いろいろな構成が可能です。
マイクロサービスは他のマイクロサービスにアクションを送って、何かの情報を得ることがあります。とはいえ、マイクロサービスはそれぞれが独立しているので、これはとても緩い依存関係です。
小さな仕事をこなすマイクロサービスをたくさん作って、それぞれが独立して、あるいは他のサービスを呼び出して、全体として何かまとまりのある仕事をするよう作っていくと、マイクロサービスによるシステムになるわけです。マイクロサービスは、改訂が容易で、タイムリーにメンテナンスできます。
ただ、これまで作ってきたウェブアプリケーションのように、サーバーにデプロイ(配備)するようなことはしません。サーバーは、ライブラリの巨大な集まりで、それによりどんなアプリケーションでも起動できます。
しかし、マイクロサービスでは、起動するのに必要なライブラリを、配備するパッケージの中に入れてしまいます。そのため、後はJVMがあればそれだけで起動できます。JVMによる実行環境があれば、大がかりなサーバーはいらないというわけです。
そして、実行環境と言えばコンテナの出番です。コンテナは独立した仮想的なアプリケーションの実行環境です。たくさんのコンテナを作って、そこに1つずつサービスプログラムを放り込んで動かします。
数が多くなるといろいろ大変になりますが、プログラマは、yamlという拡張子のファイルに、細々とした指示を書いて、作成したサービスパッケージと一緒にKubernetesという管理ソフトに渡します。Kubernetesは、自前のコンテナにパッケージをロードし、後は、いろいろうまくやってくれることになっています。
疑問に思うこと
あまり知らない頃、データベースはどうするんだろうと思っていました。伝統的な三層システムには、必ずデータベースサーバーがあります。サーバーはいらないなら、データベースサーバーはどうするのだろう・・・
実はデータベースサーバーも、コンテナの中で動かすのです。yamlファイルを書かなくてはいけませんが、逆にいうとyamlファイルを書くだけで、kubernetesがコンテナの中の1つのサービスとして起動してくれます。
各マイクロサービスは、それぞれ独立したデータベースを持ちますが、同じデータベースサービスを使って、それぞれが自分専用のデータベースを持てるので、基本的にこれまでと大差ありません。
ただ、マイクロプロファイルという、マイクロサービスを規定する規約には、HibernateやJPAのようなデータベースライブラリは、含まれません。マイクロサービスを構築するフレームワークの拡張機能として、おまけ的に使うことができるだけです。
とはいえ、マイクロサービスのフレームワークも進化しているので、もっと簡単で素晴らしい選択肢もあります(詳しくは後で)。
それにしても、一番の問題はユーザーインタフェースじゃないでしょうか。
Java言語でウェブを操作するには、MVCとかJSFとかいろいろあったのですが、それらはほぼ使えません。マイクロプロファイルに、そんなものは微塵も入っていないからです。
「ああ、だからみんなAngularとかReactとかに血眼になって、JSで作っているんだ・・・」
生粋のJavaプログラマはJSが嫌いです(よね)。あいまいな型付け、なんだか金魚のフンみたいにだらだら続く命令文。どうにも好きになれません(よね)。
しかし、これも過去の話になりつつあります。
マイクロサービスは、JSONを返すだけでなく、HTMLだって返すことができるのです。だったらそんなライブラリを作ればいいだけの話じゃないのかなぁと思っていたら、フレームワークでそれをやってくれるようになっていました!(詳しくは後で)
「それにしても、あのyamlファイルってやつ、あれはほんとによくわからん。どうかしたらイミ不明だ。わかりそうで、わかった感が湧いてこない」
なんとなくコピペして書かされている感じ。これもなんとかならんものかと思っていたのですが、「書かなくていい」やり方があることがわかりました(詳しくは次に)。
Quarkus = kubernetes native!
1年ほど前、Manning社のサイトで、タイトルに惹かれて「Kubernetes Native Microservices with Quarkus and MicroProfile」という本を、ついポチってしまいました。中身よりも、注目のキーワードを全部並べた豪華なタイトルに惹かれたのです(それに、40%オフでしたからね)。
しかし、この本を通じて初めてQuarkusについて知りました。Quarkusの凄いところは、Kubernetesについてあまり知らなくても、サービスをKubernetesにデプロイできるところです。yamlファイル? そんなものはQuarkusが作ってくれるので、書きません。Kubernetes Native、そういう作りになっているのです。これはとても驚きでした。
Quarkusというネーミングは、要するに「速い!」ということを強調したものです。サービスの起動がむちゃくちゃ速いのです。Uber-jarに手を加えたFast-jarを生成します。起動の速いjarです。
それどころか、機械語にコンパイルしたNative-jarも生成できるので、これを使えるケースでは、それはもう、物凄く速いという以外ありません。JVMもいらなくなります。
なお、このようなパッケージの生成とKubernetesへのデプロイは、コマンド一発でおわります。あっけないくらい簡単でした。
Panacheで華やかなデータベース処理
Quarkusでは、マイクロプロファイルに含まれないさまざまな機能を、拡張機能として公開しています。コマンドで、追加したい拡張機能を指定するだけで、ライブラリがPom.xmlに追加されます。
どんな拡張機能があるかは、https://code.quarkus.io を参照してください。
データベース機能も拡張機能の中にあります。それは、Panache(パナッシュ)というフランスっぽい名前でしたが、JPAを土台にしています。ただ、JPAやHibernateより、よほど使いやすいのです。
例えば、本(Bookエンティティ)を検索する次のfindメソッドの書き方を見てください。
Book.find("genre='NOVEL'", Sort.by("author"))
.page(Page.of(2, 10))
.list();
これは、ジャンルがNOVELである本を、著者の名前でソートした上、1ページに10件表示することにして、その3ページ目(ゼロから数えるので)のデータをリストに取得する、というものです。このコンパクトさ、すごいでしょう?
どこにもJPQL(オブジェクト指向なデータベース問い合わせ言語)的なものは書きません。本当にこれだけです。
しかも、細かく見ると、genre='NOVEL'に、驚きませんか?
JPQLだともっと長~い記述が必要ですが、これは、where句の中身だけでいいのです。
それに、ソーティングやページング処理まで、いっぺんにできてしまいます。
Panacheは、いろいろなメソッドを30個ほど持っていて、なかなか便利です。もう、JPAには戻れないなぁ、と思う今日この頃です。
Quteなテンプレートエンジン
いくらマイクロサービスでも、ユーザーインタフェースは必要です。確かに、JSのフレームワークを使うと、カッコいいウェブを作れますが、そこまでしなくても、なんとかJavaの世界で制御できればうれしいわけです。
今年、あるJavaのカンファレンスで、「マイクロプロファイルにはUIがないので・・・」という話をされていたのですが、すばらしいことに、QuarkusにはQuteというテンプレートエンジン拡張機能があるのです。
テンプレートエンジンですから、仕組みは違っても、機能はJSPやJSFと同じようなものです。データやデータのリストを渡すと、それを使ってテンプレートを埋め、HTMLを返します。
使い方はとてもシンプルで分かりやすいです。作成したテンプレートと同じ名前のクラスメソッドが生成されるので、それにデータやデータのリストなどを渡すと、HTMLが返ってきます。サービスでは、それをリターン文で返します。もちろん、POSTへの応答では、HTMLを返すエンドポイントにリダイレクトさせることもできます。
見かけを美しくしたい場合、ゴリゴリとCSSを書いてもいいわけですが、QuteユーザーはおおむねBootstrap押しです。BootstrapのCSSを適用した時の、"ビフォー・アフター"を図で示します。
なお、他のツール(https://unpoly.com/)を併用すると、AJAXのように部分的な画面更新を行うことができ、応答性も改善できます。
一つだけ注意しなくてはいけないことは、POSTされたパラメータの受け取りです。ASCII文字以外は、どれも文字化けします。最初は面食らったのですが、インターセプターでコード変換を行うクラスが公開されています(https://github.com/quarkusio/quarkus/issues/10323)。これを、プロジェクトの中に加えておけば、問題を回避できます。おそらく、近いうちに、UTF-8をデフォルトにするような改訂が行われるでしょう。
終わりに
思えば、インターネットの普及により、ウェブシステムへのパラダイムシフトが起こったのが2000年頃でした。UIをウェブにするという、とてもエキサイティングな変化で、世界は激変しました。
そして、やみくもにウェブシステムを開発しつづけて10年余、これじゃどうにもならなくなると皆が思い始めたころ、次のパラダイムシフトが始まりました。それがマイクロサービスです。
クラウドやコンテナ技術の普及、そして、Kubernetesのデファクトスタンダード化により、この傾向は現実味を増しています。とても悠長に構えてはいられない、そんな気になるこの頃です。
Quarkusは、クラウド初心者にお勧めのフレームワークです。簡単に、マイクロサービスを始められます。
DockerやKubernetesの使い方から入ろうとしたアナタ(実は私)、それは間違いというものです。とにかくQuarkusを使ってみましょう。DockerもKubernetesもQuarkusが勝手に動かしてくれます。それらはツールにすぎません。大事なのはソフトウェアですからね。まず、作ってみることです。
Quarkusのサイト(https://quarkus.io/)には、説明書やサンプルがゴマンとあり、日本語で読めます(上右端の地球儀アイコンで日本語になります)。ネットを探すと、使用例や報告などもたくさんあります。学習の材料には事欠きません。
あ、それからですが(これは宣伝じゃありませんよ)、まとまった日本語の資料が欲しい人は「わかりやすいJava入門編 第3版」を見てください。そこそこ始められるように書いてありますので。
それにしても、今年はいろいろありました。
メリークリスマス、そして、よいお年をお迎えください。