CISTLT-Zli 合同LT会2020 with Halloween にて発表 https://github.com/yt8492/indikate
サーバーサイドKotlin/JSのフレームワークを作った話CISTLT-Zli 合同LT会2020 with Halloween
View Slide
自己紹介HN: マヤミト会津大学26期 (学部3年)Zli 現代表GitHub: https://github.com/yt8492好きな言語: Kotlin, Java, Scala趣味: Kotlin, 同人音声, VTuberTwitter: yt8492
前回のあらすじ
Kotlin/JS- KotlinをJSにトランスパイルする技術- JSのライブラリも利用可能- Kotlinで型定義を書けばJSのコードに型を付けられる- Webフロントエンドの開発もNode.jsでサーバーサイドの開発もできるトランスパイル
kotlinx-nodejsKotlin公式が提供しているKotlin向けNode.jsラッパーライブラリhttps://github.com/Kotlin/kotlinx-nodejsNodeのAPIのKotlinの型定義を提供している(が、まだexperimentalなため不完全な模様)TypeScriptの型定義をKotlinの型定義に変換するDukatというツールで生成されている
簡単なサーバーを書いてみた
問題点- http.createServerの引数のラムダ式の中に全てを書く必要がある(多分)- Nodeのhttpパッケージだけで本格的にサーバーサイド開発するのはキツい- get("/hoge") { ... } みたいに書けたほうがよさそう(expressみたいに)
じゃあ自分でフレームワーク作るか!w
要件- フルスタックというよりはシンプルで軽量なフレームワーク- イメージ的にはexpressやKtor- ルーティング、リクエスト、レスポンスなどが簡単に扱える- JSONのシリアライズとかまではやらない- kotlinx.serializationとかでユーザーにやってもらう
ルーティングの実装- pathとmethodを簡単に指定できて、ラムダ式でhandlerを書きたい- expressの app.get("/hoge", (req, res) => {}) みたいに- path, method, handlerを持つ構造体(data class)のリストを内部で保持するようにして、get("/hoge") {} などのメソッドを呼び出すとその内部のリストに構造体がaddされるようにする- http.createServerのラムダ式の引数のrequestからpathとmethodを取得し、一致するhandlerがあればそれに処理をさせる
ルーティングの実装
リクエストを扱いやすくする- http.createServerのラムダ式の引数のrequestには各種パラメータなどが扱いやすい状態で入っていない- pathやquery parameterはurlからパースして取得する必要がある- bodyはrequest.on("data")のコールバックからとる必要がある- headerは扱えるがKotlinのIterableではないのでforEachなどの便利メソッドが使えない- 自作のRequest構造体(data class)を作成し、各種パラメータなどを扱いやすくフレームワーク側で加工する
リクエストを扱いやすくする
レスポンスを扱いやすくする- status codeやmessageを構造体の変数にして、簡単に設定できるようにする- http.createServerの実装では同じ名前のヘッダを複数回setすると最後にsetした値しか反映されないので、フレームワーク側で複数回setしても全て反映されるように吸収する- response.end()を必ず呼び出す必要があるが、それもフレームワーク側でやりたい
レスポンスを扱いやすくする
今後の課題- Path Parameterが扱えない- get("/hoge/:id") みたいに扱えるようにしたいが、ルーティング周りの実装を大きく書き換えないといけない- CORS対応くらいは簡単にできるようにしてもいいかもしれない- DBを扱うKotlin/JSのライブラリがない
リンク集前回のLTサーバーサイドKotlin/JShttps://speakerdeck.com/yt8492/js開発中のフレームワークindikatehttps://github.com/yt8492/indikate