今年6月のTypeScript Meetup #4で初公開されたTypeScript製フレームワーク「frourio (フルーリオ)」が今月のアップデートでめちゃくちゃカッコいい感じに仕上がっているので紹介します
frourioはフロントからバックエンド・ORマッパーまでのアプリ全体を一つのTypeScriptとして統合型チェックが可能になるフレームワークです
1つのディレクトリで完結するので一見するとモノリシックのようですが、型で繋がっていること以外はフロントとバックが個別のプロジェクト扱い(それぞれに別のpackage.jsonがある)なのでフロントはVercel、バックエンドはDockerでAWSにデプロイするみたいなことが可能です
新しいfrourioの特徴
- TypeScript製で最速のフレームワーク
- コマンド1発でフロントSPA + RESTサーバー + ORマッパーの環境構築
- Vercel製React Hooks「SWR」に対応
- 関数にDependency Injectionが可能
- ロゴがカワイイ
順番に解説していきます
TypeScript製で最速のフレームワーク
誤解の無いように最初に伝えておくと、実用レベルでNode.jsフレームワークの世界最速はFastifyです
FastifyにもTypeScriptの型定義はありますが、コード自体は普通のJavaScriptで書かれています
TypeScript製フレームワークというカテゴリでは名前のよく似たFoxifyが最速でした
(最後のリリースは2年以上前・・・)
そんなFastifyとFoxifyの間に割って入りNode.js全体で2位、TypeScript製では最速になったのがfrourioです
Framework | Version | Requests/sec | Latency |
---|---|---|---|
fastify | 3.7.0 | 64,873 | 1.45 |
frourio | 0.19.0 | 64,457 | 1.46 |
foxify | 0.10.20 | 57,810 | 1.64 |
nest-fastify | 7.4.4 | 57,303 | 1.65 |
express | 4.17.1 | 11,972 | 8.24 |
nest | 7.4.4 | 10,025 | 9.86 |
出典:https://github.com/frouriojs/benchmarks
突然現れたfrourioが爆速なのにはカラクリがあって、サーバーのコアがFastifyなのです
すでにある速いエンジンをラップすれば速くなるのは当たり前・・・
しかしながら、Fastifyを自分で書くよりも高速に動作します
frourioはシンプルな関数を組み合わせる設計になっていることと、ルーティングでオーバーヘッドが発生しないようコンパイル時点で型情報を基に最適化することでFastify本来のパワーを引き出すフレームワークなのです
コマンド1発でフロントSPA + RESTサーバー + ORマッパーの環境構築
※10/25現在、一部のWSL環境ではエラーが発生してインストールができません
Next.jsのcreate-next-app、Nuxt.jsのcreate-nuxt-app相当のコマンドがfrourioにもあるので環境構築は簡単です
Node.js v10系にはないflatMapを使っているのでv12/v14の環境で以下のコマンドを叩いてください
$ npx create-frourio-app
$ yarn create frourio-app
パッケージのダウンロードが終わったら、ターミナルに以下メッセージが表示され自動でブラウザが開きます
※ブラウザが開かない場合は手動でURLを打ち込んでください
open http://localhost:3000 in the browser
「Directory name」は新規作成するプロジェクトのディレクトリ名を入力します
package.jsonのnameにも使われる名前です
frourioのコアはデフォルトで選択されているFastifyがおススメです
Expressに比べて日本語情報が少ないものの、開発は活発だし何よりベンチマークが5倍以上速いです
フロントエンドはNext.jsかNuxt.jsの好きな方を選んでください
「Daemon process manager」までの項目についてもお好きなように
ORマッパーはデコレータ不要で型がきっちり付くPrismaがおススメです
今回はちょっと動かしてみるだけなのでデータベースはSQLiteにするといいです
事前インストール不要でプロジェクト内に閉じた開発が出来ます
SQLiteで使う.db
ファイルはデフォルトのまま
依存性注入のサンプルコードを見たい場合はJestを選択しCreateボタンを押します
画面にモーダルが現れ、ターミナルでインストールが始まります
インストールが終わるとブラウザが自動でリロードされてNextかNuxtのTodoアプリが表示されます
インストールのあとにビルドの工程があるのでかなり時間がかかります
Vercel製React Hooks「SWR」に対応
インストール時にNext.jsを選択すると、pages/index.tsx
に以下のコードがあります
10行目のuseAspidaSWR
というのがSWRのラッパーで、引数に渡したapiClient.tasks
をキーとして/tasks
にGETリクエストを行っています
返り値はSWRの返り値と全く同じです
実はこの引数がfrourioのコントローラと型で静的に繋がっているのです
server/api/tasks/index.js
にこのAPIの型定義があります
server/api
以降のディレクトリ名がそのままAPIのURLに対応してます
試しにresBodyの型をstringに変えてみると
Next.js: pages/index.tsx
frourio: server/api/tasks/controller.ts
Next.jsとfrourioの両方で型エラーが出るのがfrourioのスゴイところです
関数にDependency Injectionが可能
frourioはバリデータ以外全て関数で書きます
関数で書かれたコントローラーに依存性注入を行うパターンは一般に確立されていませんがfrourioでは「関数型DI」と呼んでいる方法を採用しています
インストール時にテストフレームワークとしてJestを選択するとfrourioのテストコードが含まれます
以下8行目でprismaオブジェクトを注入したfindAllTaskを定義
あとで依存性注入しやすいようにasでアップキャストしておきます
以下7行目でfindAllTaskとprintをコントローラーに注入
好きなツールを使ってテストを記述
以下7行目のコントローラーはもちろん、8行目のfindAllTaskにも依存性注入が必要なので入れ子にしています
printは依存がないのでアロー関数を直接注入します
実行結果
よく見かけるクラスベースのDIに比べて非常に簡潔に記述出来ていることが伝わるでしょうか
これはvelonaという別のライブラリを取り込んで実現したものです
(正確にはfrourioでDIを行う方法を模索し続けた結果生まれたスピンオフライブラリです)
以下の記事が参考になります
まだクラスへの依存性注入で消耗してるの?TS製の関数型DIヘルパー「velona」のススメ
ロゴがカワイイ
海外のデザイナーに発注して作ってもらったカワイイキャラクターがロゴに使われています
気に入ったらGitHubにスターを押してやって下さい
frourio
Qiitaの解説記事から来てくれた人々のおかげでfrourioのGitHubスターがあっという間に100を超えました🎉🎉
— Solufa (@m_mitsuhide) October 11, 2020
可愛いロゴ(名前はまだない)とともにTypeScript界のRailsポジションを目指して開発を続けていきます!https://t.co/wxMmaRwmEA
参考記事
以下URLでfrourioの日本語解説記事が連載される予定です
frourio でフロントエンドとバックエンドを一緒に静的型検査する
frourio でサクッと API 型定義 & コントローラーを書く