去年はこれです。ちらほらスターがもらえていたりするので、今年も更新するかという気になった。
以下の項目について技術スタックを考えていく。太字は今年になって追加したもの。
- 言語
- エディタ
- ビルドツール
- スクリプティング
- ロギング
- テスト
- 依存性注入(DI)
- アーキテクチャ
- Webフレームワーク/サーバ
- GraphQL
- フロントエンド
- RPC
- テンプレートエンジン
- JSONまわり
- RDBMSまわり
- キューイング
- Auth
- 便利なツール/ライブラリ
- ローカル開発テク
- デプロイとか
- 言語
- エディタ
- ビルドツール
- スクリプティング
- ロギング
- テスト
- アーキテクチャ / 依存性注入(DI)
- Webフレームワーク/サーバ
- GraphQL
- フロントエンド
- RPC
- テンプレートエンジン
- JSONまわり
- RDBMSまわり
- キューイング
- Auth
- 便利なツール/ライブラリ
- ローカル開発テク
- デプロイとか
- いかがでしたか?
言語
- Scala 3でよい
- 最新の3.4.1を選んでよい。保守的にやるならLTSの3.3系
- 基本的に新しいほうがコンパイル速度やパフォーマンスが良くなっていくので、新機能とは無関係に新しくするべき
- 最新の3.4.1を選んでよい。保守的にやるならLTSの3.3系
- ほとんどの著名ライブラリではScala 3に対応した感覚がある。Sparkはまだ非対応だが互換性オプションをつけてコンパイルして使ってる人をみたことがある
- Scala 3でインデントシンタックスが導入されて従来のスタイルと組み合わせられるようになった
- 個人的にはよほど便利なシチュエーションでなければ使ってない。
- コピペでインデントが壊れる、エディタによってはうまく動かない、補完のTABと競合する、といったDX面での問題があるように思う
- 他方、スライド発表や紙面では常に1〜2行程度を稼げるので重宝する
- コストとリターンを鑑みると、そんなに嬉しさがなかった
- 個人的にはよほど便利なシチュエーションでなければ使ってない。
- 新規採用で2系を利用するべきではない
- あえて選ぶ理由がない
- 2の大抵の構文は3でも使えるか、マイグレーションできる
エディタ
- LSPが動くならなんでもいい(去年と同じ)。IntelliJでもよい。
- 最近Metals(ScalaのLSPサーバ)の進歩がすさまじく、どんどん便利になっていく
- ファーストチョイスだとVSCodeかIntelliJ
ビルドツール
sbtでいい(去年と同じ)。世の中の「このライブラリの使い方」はだいたいsbt前提で書かれている- 小さなライブラリを書くみたいなシチュエーションでMillを使いたければMillでもいいのでは。
- ペライチを書くという場合にはビルドツールを使わずに
scala-cliを呼ぶのが一番良い。sbtプロジェクトへの変換機能もある
スクリプティング
scala-cli一択- ちょっとしたバッチ処理とか、ワンショットでなにかしたい場合にはこれでよい
- 依存性解決、Javaのバージョン制約、コンパイラオプションなどを一手に引き受けてくれる
- ユーザはファイルを1つ書けばよい
ロギング
- Scribeがかなり良い
- ゼロコンフィグで使える
- JVM、Scala.js、Nativeで動作する
- カスタムしやすい
- Javaっぽい面倒なところがない
テスト
- ScalaTestが定番
- 最近は公式(Scalameta)がMUnitを作って推している https://scalameta.org/munit/
- そこまで複雑でなければMUnitでもいいのではないか
- assertした結果が違う場合、詳細なDiffを表示してくれる機能が最近追加された
アーキテクチャ / 依存性注入(DI)
- Airframe DIがおすすめ airframe-di: Dependency Injection · Airframe
- 手法として軽量で、クセがない(クラスのコンストラクタ引数として渡してくれる)
- コンパイルタイムにチェックできないのがデメリット
- 伝統的にはCake Patternが使われがちだったが、ボイラープレート化しがち
- Macwireも有名だが使ったことがないのでノーコメントで・・・
- アーキテクチャとしてはDDDが一番Scalaの得意とするところだと思う。
Webフレームワーク/サーバ
- そんなに複雑なことをやらない場合
- エンドポイント定義ライブラリとしてTapirを使う
- 非常に便利
- その上で、好きなHTTPサーバとのバインディングを利用する
- シンプル重視、ストリーミングに強いhttp4s
- LINEヤフー製、機能豊富なArmeria
- パフォーマンスと安定性は折り紙付き、Akka/Pekko HTTP
- Oracle製、LoomのVirtual Threadを利用するHelidon Nima
- Cats EffectやZIOを最初からやる気ならそのエコシステムのを使うとよさそう
- エンドポイント定義ライブラリとしてTapirを使う
- もしくは最初からPlay Frameworkを利用するのもよい
Tapirの解説記事そのうち書きたいですな。
おすすめのHTTPサーバあったら教えてほしい。
GraphQL
- 老舗のSangriaか、ナウいCaliban、の二択
- 個人的にCalibanを推したい
- 素直で使いやすい(主観)
- パフォーマンスが売り
- スキーマファイルからの型定義生成機能がある
Calibanもまたそのうち記事を書きたい。
フロントエンド
Scala.js...と言いたいところですが、いわゆる「フロントエンド開発」をやりたいのであれば素直にReactやVueなどを使うのがいいと思います。Scala.jsは非常に成熟しており、本当に良くできていて、Scalaがそのまま動くのですが、そのわりに関連エコシステムはまだまだ貧弱、というのが理由です。
TypeScriptにおける数多のライブラリが数々の妥協と包摂によって世界を席巻したのと比べると、Scalaのフロントエンドライブラリは各々の最強の世界観で地上を統一せんとするフシがけっこう強く、DOMもCSSも全部Scalaで書こうとしてしまう。これが世界を席巻するイメージはまだできない。「全部理解してる人なら書けると思うけどそれでチーム開発とかは無理じゃないですか、デザイナにScala書けって言うんですか」というのが今の感想。
他方、ESMを吐き出すことは普通にできるので、これをうまく利用してバックエンドを呼び出すためのグルーコードは(Next.jsのServer Actions的な感じで)Scala.jsに作らせて、これをTypeScriptから呼ぶといったことは可能なので、そのあたりの用途で使うのは全然アリだと思う。今のところScalaはd.tsを生成できないようだが。
RPC
- Tapirが便利
- Tapirはサーバ側の定義だけではなくクライアントサイドのコードも生成できる
- バックエンドのAPI定義から、これを呼び出すScala.jsのコードを生成できて便利
- Airframe RPCも良いと思う。しかしTapirを使ってるならTapirでいいかな・・・という感じ
テンプレートエンジン
- 型安全にやりたいならTwirl
- プラグインを入れるのでちょっと重厚
- Mustacheなどの記法でもうちょっとゆるくやりたいならScalate
- 去年のうちにScala 3対応していてありがたい
Scalateの練習もそのうちやりたい。
JSONまわり
- まだファーストチョイスでCirceでいいのではないか
- デファクトの地位にまだいると考えてよい
- たいていのライブラリでCirceバインディングが提供される程度には人口がある
- しかし、最近そんなにリリース頻度が高くない
- 成熟しているという説もある
- 最近だとjsoniter-scalaがめちゃくちゃ活発に開発されている
- Argonautもよさそうだったけど、ドメインを失効させてドキュメントが読めない
JSONライブラリまわりの動向あまり詳しくないので教えてほしい。
使いやすいJSONライブラリを公式が提供してほしいという気持ちもある・・・。
RDBMSまわり
SlickかScalikeJDBCでいいのでは。
- Slick
- Prismaライクな便利なメソッドを使える
- ScalikeJDBC
- 素朴にSQLを書きたい人向け
Slickの記事も書きたいですな。
ちなみにコネクションプールはHikariCPが定番です。
キューイング
最近はクラウド大時代なのでジョブキューみたいなやつにはSQSみたいなSaaSを使うのがいいと思うけど、オンプレでやりたければFireworqみたいなミドルウェアを入れるか、Scalaの中でCats Effectを使っていい感じに非同期処理する君を書くとよいと思う。負荷管理みたいなことを考えるとホスト分けたりしたくなる。
ここもそんなに詳しくないので自信ニキがいたら教えてほしい。
Auth
爆速でWebアプリを作るとなると、いまどきは自前で認証というのもやりたくないので、なるだけ外部でやる前提。
最近Hanko.ioを使って便利だった。これでちょっとした認証は書けると思う。バックエンドではJWTを検証するだけでいい。Passkey使えるのがとても良い。
JavaのSDKもあるので便利。
ほかにもCloudflare Accessも良かった。
便利なツール/ライブラリ
コンフィグ
Typesafe Configが定番だけど、最近は同じファイルを読めるPureConfigをよく見掛ける。
使ったことはほぼないけど、素朴で使いやすそうな感じなのでそのうち採用してみたい。
コマンドラインパーサ
- Catsを前提にしていいならDecline
- 素朴なやつでいいならmainargsがいいと思う
- lihaoyiエコシステム
ローカル開発テク
- 最近dotenvxというのを知ったので便利そうと思っているけれど、環境の切り替えだったらそれこそTypesafe ConfigとかPureconfigで事足りそう。dotenvxは暗号化できるのでそこが便利だと思う
- sbt-revolverを使って自動リロード・自動サーバ再起動を行う
デプロイとか
- ペライチのスクリプトの場合、
scala-cli packageすると勝手にJARを作ってくれる - sbtだと
sbt-assemblyでJARに固めてHTTPサーバを起動する sbt-native-packager- Docker Imageを生成したりネイティブイメージを生成したりできる便利なプラグイン
- これでDocker Image作ってそのままデプロイすれば最短ルートな気がする
いかがでしたか?
2024年だとまぁこんな感じじゃない?というのを紹介しました。異論はどしどし教えてください。