Scalaで、独自のWebフレームワークをゼロから作ってみた
- はじめに
- なぜ作成したのか
- どんな感じで作っていったのか
- どんな機能を作ったのか
- 今後どんな機能を作りたいか
- おわりに
1. はじめに
こんにちは、ネクストビートの富永です。
今回はフレームワークを作成したので、それに関してのブログになります。
フレームワークと言っても、OSSのような第三者に使っていただくようなものを想定して作ってはおらず、あくまで自分の勉強用に作成を行なったものになります。
なぜ作成したのかや、今後どんな機能を作りたいかを中心に記載していきます。
以下が作成を行なったフレームワークになります。
まだ、マイナーバージョンでほぼほぼ機能はありません。。。
2. なぜ作成したのか
まずどうして作成を行なったのかについてですが、単純に作ってみたかったというのが一番大きな理由です。
好奇心的な理由をなくすのであれば、現在弊社で使用しているPlay Frameworkの構造を知りたいと思ったからです。
(あ、これも好奇心でした)
また、個人開発でCats EffectのIOについても勉強しており、その派生でIOを使用しているライブラリである、http4sやdoobieも触っていました。
特に目的もなく、ただただチュートリアルをやったりドキュメントを読んだりしているだけの勉強をしていた時に、ふと思ったのです。
「あれ、これ全部まとめてフレームワークにしたら面白いんじゃね」と、
思った時には、もう「よし、フレームワークを作ろう」というウッキウキのワックワクな状態なので、大層な理由は考えなかったです。
結局好奇心でした。
思いついてからは、以下のような感じを想像してました。
(DBは弊社がSlickを使用しているので当てはめました)
Akka HTTP × Future × Play-Slick = Play Framework
http4s × IO × doobie = Lepus Framework
3. どんな感じで作っていったのか
フレームワークを作ろうと決めてから最初に行ったのは、Play Frameworkのコードを読み漁ることでした。
読み漁ると言っても全てを満遍なくというより、最初はsbt周りから調べていきました。
なぜかというと、自作フレームワークはPlay Frameworkを参考にして作ろうと考えていたからです。
(というかフレームワークをPlay以外使ったことなかった。。。)
まず、複数プロジェクトの構成であったり、依存関係や使用ライブラリ、Play Frameworkの起動設定周りなどの基盤を調べました。
Play Frameworkをクローンしてきて、デバッグを仕込みながら1つ1つ紐解いていきました。(これだけで至福の時間でした〜)
ある程度わかってからは、実際にフレームワーク用のプロジェクトを作成し始めました。
ベースとなるプロジェクトができてきたら、次はhttp4sを使用したルーティング周りの構築を行なっていきました。
こちらも同様にコードをクローンしてきて、デバッグを仕込みながら1つ1つ紐解いていきました。(これも至福の時間でした〜)
このような感じで、使用するライブラリや参考にするフレームワークなどいろんなOSSのコードを参考にして実装を進めていきました。
4. どんな機能を作ったのか
4.1 http4sのルーティングをラップして、フレームワークで指定したルーティングの設定を行うようなルーティング機能を実装しました。
Q. なぜhttp4sの実装をそのまま使わずラップして、実装を行なったのか
A. ルーティング部分とロジック部分の分離を行いたかったからです。
Play Frameworkのルーティングは、routesファイルに一覧で記載できてとてもみやすいものになっているのですが、ルーティングとコントローラーであるロジックを分離することができなくなっています。
(できる方法があったら教えてくださいmm)
何が不便なのかと言われれば、特段問題はないのですが、今回作ろうと思ったフレームワークはルーティングの設定を書いておくだけで、Open APIのドキュメント生成ができるようにしたかったからです。
もう少し具体的に書くと、バックエンドエンジニアがルーティングの設定を書いておけば、Open APIのドキュメント生成を行うことができ、かつそのドキュメントを使用してモックサーバーを立てられるようにしたかったのです。
もしこれができれば、ロジック処理の完成を待つことなくフロントエンドエンジニアはモックサーバーを利用して開発を行うことだできるようになります。
このようなスキーマ駆動開発をフレームワークで矯正できるようにしたかったからです。
(弊社全部自分でやるから全く需要なし。。。)
4.2 フレームワークで指定したルーティングの設定からOpen APIのドキュメントを生成する機能を実装しました。
理由は4.1で述べた理由と同じです。
ただこれがとても難しかった。。。
何が一番難しかったかというと、リクエストボディやレスポンスボディなどのパラメータをその型情報だけで、Open APIの形式沿ったyamlファイルに書き出すことです。
全くやり方が思いつかなかったし、調べてもそんなもの出てこなかった。
そりゃどこで使うねんという機能だったから調べても出てこないわけだ。
最終的には、magnoliaというライブラリを使用して実装を行いました。
これは、Play Frameworkと同じように参考にしていたOSSであるtapirで使用されており、見つけることができました。
(ここで初めてmacroに触れる)
もし、tapirを参考にしていなかったら途中で見つけられずに、折れてたかもしれない。。。
見つけてからは、magnoliaやtapir、circeなどを参考にどんどん実装を行なっていきました。
5. 今後どんな機能を作りたいか
今後どんな機能を作りたいかはたくさんあります。
まず、コントローラ部分も実装を行いたいですし、doobieを使用したDB周りも実装したいです。
あとはログ周りや、PlayのようなDIも実装したいです。
Playで実装されてる継続的ビルド(アプリを起動してる時に、コードを修正すると自動でコンパイルされて起動し直すやつ)も実に興味深いので、実装したいです。
あとは、今サーバー部分はhttp4sで使用されている、BrazeServerを使用していますし、非同期部分もCats Effectをそのまま使っています。
なので、この2つに関しても内部を読みにいってちゃんと理解して実装を行なってみたいものです。
このような感じで、おそらく実装したいものは今後も無限に出てくると思います。
なので、全部実装します。
6. おわりに
フレームワークとしては機能はほとんどないし、おそらくバグも多いかもしれませんが、自分が作りたかった1機能を作れたことは素直に嬉しかったです。
勉強用のフレームワークだったので、いろんなOSSのコードを参考に作りましたが、そのおかげでOSSのコントリビューターにもなることができました。
OSSのコードを参考にしていると、自分の頭では思いつかないようなやり方がたくさんあったので、とてもいい勉強にもなりました。
これからもフレームワークにいろんな機能をつけていくのが、楽しみで仕方ありません。
また、機能を追加できたらブログにするかもしれないので、そちらも読んでいただけると嬉しいです。
今回は、フレームワークを作ってみた感想のようなブログになってしまいましたが、最後まで読んでいただきありがとうございました。
PS: 僕の書いたウサギちょーかわいい
We are hiring!
「人口減少社会において必要とされるインターネット事業を創造し、ニッポンを元気にする。」
を理念に掲げ一緒に働く仲間を募集しております。