コンポーネントモデル 数値しか渡せなかったところから、言語をまたぐ合成まで

WASMのモジュールが素で扱える型は、i32、i64、f32、f64の四つだけです。文字列をひとつ渡すにも、線形メモリ(モジュール専用の作業領域)のどこに何バイト置いたかを呼ぶ側と呼ばれる側で申し合わせ、そのうえで整数を二つ渡します。言語ごとに違うグルーコード(橋渡しの繋ぎコード)が書かれ、噛み合わなければ落ちます。コンポーネントモデルは、この上に型のある境界を置く仕組みです。

Preview 1 の形

WASIのPreview 1は、POSIXに似た関数の集まりでした。ファイルディスクリプタを受け渡して fd_read や fd_write を呼びます。C言語の作法をそのまま持ち込んだ形で、Cから移植する分には都合がよかったものの、言語をまたいで部品を組む用途には向いていませんでした。

WIT で境界を先に書く

コンポーネントモデルでは、インターフェースを .wit に書きます。レコード、バリアント、リソースが使え、list<string> のような形もそのまま書けます。

interface reader {
  record entry { name: string, size: u64 }
  list-dir: func(path: string) -> result<list<entry>, string>
}

この定義からRustやJavaScript向けのコードを生成する道具(wit-bindgen、jcoなど)があり、両側が同じ .wit を見ている限り組み合わせは成立します。実装言語は問いません。Rustで書いたコンポーネントとJavaScriptで書いたコンポーネントを、そのまま繋げられます。

world は、渡す能力の一覧でもあります

world は、そのコンポーネントが何を輸入し何を輸出するかの宣言です。ファイルシステムを使うなら輸入に書きます。書かなければ、実行環境がどれだけ機能を持っていても中からは触れません。

そのためworldは仕様書であると同時に、権限の一覧にもなっています。何ができるコードなのかを、動かす前に読んで確かめられます。監査の単位が「このコンポーネントは何を輸入しているか」という具体的な問いになる点が、実務では大きく効きます。

0.2 と、その先

WASI 0.2は2024年に安定版となり、CLIとHTTPの世界(wasi:cli、wasi:http)が固まりました。いま進んでいるのは非同期を組み込んだ0.3系で、Wasmtimeは両方を並行して持っています。

非同期が入ると、ストリームをコンポーネントの境界をまたいで扱えるようになります。HTTPのリクエストを受けながら順に返す、という形がようやく素直に書けます。

粒度を細かくできます

部品を差し替えても境界が壊れません。実装言語を変えても、.wit が同じなら呼ぶ側は気づきません。

コンテナのように一つずつがOSを抱え込むこともないため、分けたぶんだけ重くなるということがありません。権限を細かく切りたいとき、切るほど運用が重くなるのでは意味がありませんが、ここではその心配が小さくなります。

「何を渡すか」を決める仕組みと、「部品としてどう組むか」を決める仕組みが、同じ宣言の上で繋がっています。外部に開発を委託した部品を自社の仕組みへ組み込む場合、その部品が何を輸入しているかを .wit から確かめられるかどうかが、受け入れ判断の材料になります。

まずはお気軽にご相談ください。目的や課題を丁寧にヒアリングし、
ご予算や納期に合わせた最適なご提案をいたします。

まずはお気軽にご相談ください。
目的や課題を丁寧にヒアリングし、
ご予算や納期に合わせた最適な
ご提案をいたします。

無料相談はこちら