← レッスン一覧に戻る レッスン 28 / 28
上級 api
Wasmコンポーネントモデル
現在のWasmの問題
今日のWebAssemblyは4つの型のみをサポートしています: i32、i64、f32、f64。それ以外(文字列、構造体、配列)は手動でエンコードする必要があります:
現在: Rust String → UTF-8バイト → ポインタ + 長さ → JSデコード
未来: Rust String → string(ネイティブWasm型)→ JS stringwasm-bindgen はRust↔JSではこの問題を解決しますが、Rust固有です。GoモジュールがカスタムグルーなしにRustモジュールの関数を呼ぶことはできません。
コンポーネントモデルが解決するもの
| 問題 | 現在 | コンポーネントモデル |
|---|---|---|
| 型 | i32/i64/f32/f64のみ | 文字列、リスト、レコード、バリアント、オプション、リザルト |
| 相互運用 | 言語固有のグルー | 言語非依存のWITインターフェース |
| 合成 | モノリシックモジュール | インポート/エクスポート可能な合成可能コンポーネント |
| 依存関係 | 手動リンク | パッケージレジストリ(warg) |
WIT: WebAssembly Interface Types
WITはコンポーネントのインターフェース定義言語です:
// my-api.wit
package example:my-api;
interface types {
record user {
name: string,
age: u32,
email: option<string>,
}
enum role {
admin,
editor,
viewer,
}
variant error {
not-found(string),
permission-denied,
internal(string),
}
}
interface users {
use types.{user, role, error};
create-user: func(name: string, age: u32) -> result<user, error>;
get-user: func(id: u32) -> option<user>;
list-users: func() -> list<user>;
}
world my-app {
import wasi:http/outgoing-handler;
export users;
}WIT型
| WIT型 | 説明 | 例 |
|---|---|---|
string |
UTF-8文字列 | "hello" |
bool |
ブーリアン | true |
u8..u64, s8..s64 |
整数 | 42 |
f32, f64 |
浮動小数点数 | 3.14 |
list<T> |
動的配列 | list<string> |
option<T> |
null許容 | option<u32> |
result<T, E> |
成功またはエラー | result<user, error> |
record |
名前付きフィールド(構造体) | record { name: string } |
variant |
タグ付きユニオン(列挙型) | variant { a(u32), b } |
tuple<T, U> |
匿名タプル | tuple<string, u32> |
Rustでコンポーネントをビルドする
# cargo-componentをインストール
cargo install cargo-component
# 新しいコンポーネントプロジェクトを作成
cargo component new my-component
cd my-component// src/lib.rs
#[allow(warnings)]
mod bindings;
use bindings::Guest;
struct Component;
impl Guest for Component {
fn greet(name: String) -> String {
format!("Hello, {}!", name)
}
}
bindings::export!(Component with_types_in bindings);# コンポーネントをビルド
cargo component build --release
# 出力は.wasmコンポーネント(コアモジュールではない)コンポーネントの合成
複数のコンポーネントを組み合わせることができます:
┌─────────────────┐ ┌─────────────────┐
│ 認証コンポーネント│────▶│ APIコンポーネント │
│ (Rust) │ │ (Go) │
└─────────────────┘ └────────┬────────┘
│
┌────────▼────────┐
│ DBコンポーネント │
│ (Python) │
└─────────────────┘各コンポーネント:
- 型付きWITインターフェースを公開
- 任意の言語で記述可能
- サンドボックス化 — インポートしたものだけにアクセス可能
- 他のコンポーネントを変更せずに置換可能
タイムライン
| ステータス | 機能 |
|---|---|
| ✓ 安定版 | コアWasm(モジュール、メモリ、関数) |
| ✓ 安定版 | WASIプレビュー1(ファイルI/O、環境変数、引数) |
| ✓ 安定版 | コンポーネントモデル仕様 |
| ✓ 利用可能 | cargo-component、jco、wasmtimeサポート |
| 進行中 | WASIプレビュー2(HTTP、ソケット、キーバリュー) |
| 進行中 | wargパッケージレジストリ |
| 計画中 | ブラウザでのコンポーネントサポート |
| 計画中 | バンドラーでのコンポーネントリンク |
なぜ重要なのか
コンポーネントモデルはWasmを「ブラウザ内の高速コード」からユニバーサルなソフトウェアコンポーネントフォーマットへと変えます:
- Rustで画像処理を書く → Python、Go、JSから利用
- プラグインシステムを構築 → ユーザーは任意の言語でプラグインを記述
- マイクロサービス → 各サービスがサンドボックス化されたWasmコンポーネント
- エッジコンピューティング → CDNエッジでコンポーネントを合成
試してみよう
Run をクリックして、コンポーネントモデルの概要を確認しましょう — 提供される機能、WIT構文、利用可能なツールを確認できます。これがWebAssemblyの未来の方向性です。
試してみる
チャプタークイズ
すべての問題に正解してレッスンを完了しましょう