この記事は Scala Advent Calendar 2021 14日目の記事です。
Scalaで一番easyな構成を考えたい
Scalaでマスタメンテや運用補助の簡単なアプリを手軽に作りたいときどうしましょう?
requirements
- マスタメンテ画面など手軽に作りたい
- フロントとサーバーが分かれてないほうがいい
- フロントとサーバーを統合するのでOpenAPIやTapirはむしろ不要!
個人的コンテキスト
しばらくvueのプロジェクトの改善をやっていて、大きく育ったSFCをコンポーネントに切り出すのがつらかった。誰でも安全確実に高速でリファクタリングできないと意味がない!
playframework + twirlは楽だけど そもそもhttpすらいらない よねという話をAirframe RPCの話題で聞いていて、もっとシンプルなRPCないかなと探してみた。。。
すると、さすがlihaoyiさんがすでに作ってた!
// shared interface
trait Api{
def add(x: Int, y: Int, z: Int): Int
}
traitがそのままAPIの定義になる
// server-side router and implementation
object Server extends autowire.Server...
一行でサーバーになるらしい。すごい。
object ApiImpl extends Api
def add(x: Int, y: Int, z: Int) = x + y + z
}
traitを実装するとAPIが完成!
こちらは↓はクライアントサイド
// client-side callsite
import autowire._ // needed for correct macro application
object Client extends autowire.Client...
Client[Api].add(1, 2, 3).call(): Future[Int]
// | | |
// | | The T is pickled and wrapped in a Future[T]
// | The arguments to that method are pickled automatically
// Call a method on the `Api` trait
これだけでRPC(リモートプロシージャーコール)ができる!
#もうサーバーこれでよくないですか?
動くサンプルを用意したかったんですが、先週Twitterで炎上していて準備する時間が足りなくなりました。
ちょうど昨日110416さんがlaminarの紹介してたのでフロントはそちらに譲ります。
https://zenn.dev/110416/articles/997e1932fa0010
LaminarとAutowireの連携については、Gitterで聞いてみたら、
「AutowireはLaminarとうまく連動します。RPCでも何も特別なことはなくてFutureで返ってくるならこんなふうに簡単にできます」
と、コードも共有してくれました
div(
Signal.fromFuture(makeRpcCall()) --> myResponseObserver
)
or
val responseSignal = Signal.fromFuture(makeRpcCall())
div(
child <-- responseSignal.map(...)
)
とのことでした。
Laminarを使ったときにデザインってどうしてますか?という感じの質問には
LaminarはWeb Componentsとの統合を内蔵しているので、とても簡単にWeb Componentsを利用できます。
また、Laminar用のMaterial UI Webコンポーネントのライブラリがあります。https://github.com/uosis/laminar-web-components 正確には、このライブラリはGoogleのMaterial UI Web Componentsへのインターフェースのセットです。これらのインターフェースは100%完全ではありませんが、良いスタートです。CSSライブラリについては、そのほとんどがCSSクラスに基づいており、それはLaminarでも問題なく動作します。
IuriiはTailwind CSSが好きで、そのライブラリを使ったLaminarコンポーネントのサンプルをいくつか作りました。https://laminext.dev/tailwind 。決して完全なセットではありませんが、どのように実装されているかを見て、良いテクニックを学ぶことができるでしょう。
デザインのオプションが用意されてるのも安心ですね!
今回は時間がなく動作する完全なサンプルを用意できませんでしたが、出来次第共有したいと思ってます。
それではみなさんよいScalaライフを!