← レッスン一覧に戻る レッスン 25 / 28
上級 api
ブラウザ外のWasm(WASI)
WASIとは?
WASI(WebAssembly System Interface)は、Wasmをブラウザ外で実行できるようにします — サーバー、エッジネットワーク、IoTデバイス、CLIツールで動作します。ブラウザが必要としないシステム機能(ファイルI/O、ネットワーキングなど)への標準化されたAPIを提供します。
ブラウザWasm WASI Wasm
┌───────────────┐ ┌───────────────┐
│ Web API │ │ システムAPI │
│ (DOM, Canvas, │ │ (ファイル, Net,│
│ Fetch等) │ │ Env, Clock) │
├───────────────┤ ├───────────────┤
│ Wasmランタイム │ │ Wasmランタイム │
│ (V8, Spider- │ │ (Wasmtime, │
│ Monkey) │ │ Wasmer) │
└───────────────┘ └───────────────┘2つのWasmターゲット
| ターゲット | 実行場所 | API |
|---|---|---|
wasm32-unknown-unknown |
ブラウザ | web-sys経由のWeb API |
wasm32-wasip1 |
サーバー/CLI | WASI(ファイル、環境変数、引数) |
はじめ方
# WASIターゲットを追加
rustup target add wasm32-wasip1
# WASIランタイムをインストール
cargo install wasmtime-cli
# プロジェクトを作成
cargo new --bin my-wasi-app
cd my-wasi-app// src/main.rs — ネイティブRustと同様にWASI上で動作
use std::fs;
use std::env;
fn main() {
// コマンドライン引数
let args: Vec<String> = env::args().collect();
println!("Args: {:?}", args);
// ファイルI/O(サンドボックス内)
fs::write("output.txt", "Hello from WASI!").unwrap();
let content = fs::read_to_string("output.txt").unwrap();
println!("Read: {}", content);
// 環境変数
if let Ok(val) = env::var("MY_VAR") {
println!("MY_VAR = {}", val);
}
}# ビルド
cargo build --target wasm32-wasip1 --release
# wasmtimeで実行(ファイルアクセスを許可)
wasmtime --dir=. ./target/wasm32-wasip1/release/my-wasi-app.wasmケーパビリティベースセキュリティ
WASIはサンドボックスモデルを採用しています — Wasmモジュールはデフォルトでアクセス権がありません。ケーパビリティを明示的に付与します:
# 何にもアクセスできない
wasmtime app.wasm
# カレントディレクトリへのアクセスを許可
wasmtime --dir=. app.wasm
# 特定のパスへのアクセスを許可
wasmtime --dir=/data::/app/data app.wasm
# 環境変数を許可
wasmtime --env MY_VAR=hello app.wasmこれはネイティブ実行ファイルよりも根本的に安全です — Wasmモジュールは明示的に許可しない限り、ファイル、ネットワーク、環境変数を読み取れません。
ユースケース
| ユースケース | WASIを使う理由 |
|---|---|
| エッジコンピューティング(Cloudflare Workers) | コールドスタート |
| プラグインシステム | アプリ内で信頼できないコードを安全に実行 |
| CLIツール | 一度書けばWasmランタイムのある任意のプラットフォームで実行 |
| サーバーレス関数 | コンテナより小さく、速く、安全 |
| 組み込み/IoT | 極小のランタイムフットプリント(約5MB) |
WASI vs ブラウザWasm
| 機能 | ブラウザ | WASI |
|---|---|---|
| DOMアクセス | ✓ | ✗ |
| ファイルシステム | ✗ | ✓(サンドボックス内) |
| ネットワークソケット | ✗(Fetchのみ) | ✓(サンドボックス内) |
| 起動時間 | ~100ms | ~1ms |
| サンドボックス | ブラウザサンドボックス | ケーパビリティベース |
Cloudflare Workersの例
Cloudflare WorkersはWASI Wasmを実行できます:
// WASIにコンパイルされるシンプルなHTTPハンドラー
fn main() {
let body = "Hello from Rust + WASI on Cloudflare!";
println!("Content-Type: text/plain");
println!("Content-Length: {}", body.len());
println!();
print!("{}", body);
}未来: コンポーネントモデル
WASIはコンポーネントモデルに向けて進化しています — 型付きインターフェースをインポート/エクスポートできる、合成可能なWasmモジュールです(バイトだけでなく)。これにより以下が可能になります:
- Wasmモジュール同士の呼び出し
- 言語に依存しないインターフェース
- Wasmコンポーネント用のパッケージマネージャー
試してみよう
Run をクリックして、WASIのケーパビリティを確認しましょう。コードはWASIが提供するものとコンパイル方法を一覧表示します。ローカルで wasmtime を使って実行し、ファイルI/Oや環境変数の動作を確認してみてください。
試してみる
チャプタークイズ
すべての問題に正解してレッスンを完了しましょう