ロゴ ロゴ

ノンブロッキングIOなHttp Web フレームワークを作った【車輪の再発明】

なぜか

タイトルに書いてる通り, 車輪の再発明をしてしまいました.

しかし深いわけがありました.

というのも大学の授業で, Javaを使った成果物を提出する必要があったのですが, Java 16標準API以外のライブラリが使用できないというルールでした.

私はJavalinというWebフレームワークを使って5chみたいなWebアプリを作ると声高に宣言していたので, ここから逃げちゃダメだ!という思いでしこしこフレームワークから作り始めることにしました.

できたもの

NginJ(nginxのJava版 というネーミングセンスのかけらもないなにか)
NginJ Github

・GET/POST/PUT/UPDATE/DELETEリクエスト受付
・パスパラメーター受け取り
・フォームパラメーター受け取り
・Javaのインスタンス変数をJSONに変換

コード例

このHttpServerクラスの後ろ側で動いている処理をすべて実装しました

import jp.toufu3.nginj.http.HttpServer;
import java.util.Map;
import java.util.List;

//Path param name is 'id'
HttpServer.get("/route/:id",(ctx)->{
    String pathParam = ctx.req.getPathParams().getOrDefault("id","empty");
    ctx.res.setBody(pathParam);
});

HttpServer.post("/",(ctx)->{
    ctx.res.setJSON(Map.of("A",List.of(1,2,3)));
});
//TCP 80 port receive
HttpServer.get().start(80);

こんな感じでパスパラメータの取得やフォームパラメータの取得といったWebフレームワークに標準搭載されているものや, Javaのリフレクションをフル活用したJavaObject->JSONコンバートまでやってくれるようになってます.

またこのWebフレームワークは, リクエストのたびにスレッドを立ち上げるApache方式ではなく, 1つのスレッドを無限ループにして, ひたすらリクエストを受け付けて, リクエストパスに関連付けたコールバックを呼び出す方式ですので, クライアントが10万接続してきても耐えられます!()

感想

短い間でしたが, 個人的なハッカソンみたいで楽しかったです(KONAMI感)

また, パスパラメータやパスに関連付けて登録された処理を呼び出す際のルートマッチの処理などのWebフレームワークの裏側を自分で実装したことでより深くWebフレームワークに必要な機能を理解でき(たような気がし)ました.

またJavaでノンブロッキングIOを実装する際, あまりに日本語の参考資料が少なく, かろうじて存在していたコードをコピペしてしまいました. ごめんなさい.

時間がかかったのはやはりJSON化でした.
GSONやJacksonってどうやって動いてるんですか?

次はJSON→JavaObjectあたりを実装したり, HTTPリクエストヘッダ改ざん攻撃に対処する機能あたりが欲しいかもしれません

もしくはリバースプロキシみたいな機能も欲しかったり〜〜?
あとCPUのコア数文のスレッドだけ立ち上げてそこでノンブロッキングIOな処理をさせることでNode.jsの上位互換を目指してもいいかもしれない.

次回のお楽しみ.

コメント入力

関連サイト