Cloudflare Workers は workers-rs crate ↗ 経由で Rust をサポートします。これにより、Runtime API と、Workers KV、R2、Queues などの開発者向けプラットフォーム製品への バインディング を、Rust コードから直接使えます。
このガイドに沿って進めると、Rust だけで Worker を構築する方法がわかります。
このガイドを始める前に、次のものを用意してください。
rustup target add wasm32-unknown-unknown- 次のコマンドで入れる
cargo-generateサブコマンド:
cargo install cargo-generateターミナルを開き、次のコマンドを実行して、Rust の Worker プロジェクトテンプレートを生成します。
cargo generate cloudflare/workers-rsプロジェクトは指定した名前の新しいディレクトリに作成されます。その中に次のファイルとフォルダーがあります。
Cargo.toml- Rust のCargo↗ パッケージマネージャー向けの標準的なプロジェクト設定ファイルです。テンプレートには、Workers 上の Wasm 向けのベストプラクティス設定があらかじめ入っています。wrangler.toml- Wrangler の設定です。worker-buildを呼び出すカスタムビルドコマンドがあらかじめ入っています(Wrangler のバンドル を参照)。src- Rust のソースディレクトリです。Hello World Worker があらかじめ入っています。
最初の Worker を作成したら、wrangler dev コマンドを実行して、Worker を開発するためのローカルサーバーを起動します。開発中に Worker をテストできます。
npx wrangler devWrangler を初めて使う場合は、Cloudflare アカウントでログインするために Web ブラウザーを開こうとします。
http://localhost:8787 ↗ を開いて、実行中の Worker を確認します。コードを変更すると再ビルドが走り、ページを再読み込みすると Worker の最新の出力が表示されます。
プロジェクトが生成されたら、Worker のコードを書きます。Worker のエントリポイントは src/lib.rs にあります。
use worker::*;
#[event(fetch)]
async fn main(req: Request, env: Env, ctx: Context) -> Result<Response> {
Response::ok("Hello, World!")
}workers-rs は、Worker の JavaScript API に近い Runtime API を提供し、Workers のプラットフォーム機能との統合を可能にします。API の詳細は docs.rs/worker ↗ を参照してください。
このマクロで、Worker のエントリポイントを定義します。event マクロは次のイベントをサポートします。
fetch- 受信した HTTP リクエストによって呼び出されます。scheduled-Cron Triggersによって呼び出されます。queue- Queues からの受信メッセージバッチによって呼び出されます(Cargo.tomlでqueue機能が必要です。workers-rsの GitHub リポジトリとqueues機能フラグ ↗ を参照)。start- Worker の初回起動時に呼び出されます(パニック時のフックのインストールなど)。
fetch ハンドラーは、JavaScript API と同じ 3 つの引数を提供します。
受信リクエストを表すオブジェクトです。ヘッダー、メソッド、パス、Cloudflare プロパティ、ボディへのアクセス用メソッドが含まれます(非同期ストリーミングと、Serde ↗ による JSON デシリアライズに対応)。
Worker の バインディング へのアクセスを提供します。
Secret↗ - Cloudflare ダッシュボード、またはwrangler secret putで設定したシークレット値です。Var↗ -wrangler.tomlで定義した環境変数です。KvStore↗ - Workers KV 名前空間バインディングです。ObjectNamespace↗ - Durable Object バインディングです。Fetcher↗ - 別の Worker への サービスバインディング です。Bucket↗ - R2 バケットバインディングです。D1Database↗ - D1 データベースバインディングです。Queue↗ - Queues プロデューサーバインディングです。Ai↗ - Workers AI バインディングです。Hyperdrive↗ - Hyperdrive バインディングです。AnalyticsEngineDataset↗ - Analytics Engine バインディングです。DynamicDispatcher↗ - Dynamic Dispatch バインディングです。SecretStore↗ - Secrets Store バインディングです。RateLimiter↗ - Rate Limiting バインディングです。
waitUntil(遅延非同期タスク)と passThroughOnException(例外時に通過させる)へのアクセスを提供します。
fetch ハンドラーは Response ↗ の戻り値型を想定しています。クライアントへの非同期ストリーミングレスポンスに対応しています。Worker からのサブリクエストの戻り値型でもあります。ステータスコードとヘッダーへのアクセス、ボディの非同期ストリーミング、Serde ↗ による JSON デシリアライズ用のメソッドがあります。
1 つの Worker から複数のパスを提供するための便利な ルーティング API ↗ を実装しています。worker-rs の GitHub リポジトリにある Router の例 ↗ を参照してください。
プロジェクトの設定が済んだら、Worker を *.workers.dev サブドメイン、または設定済みの カスタムドメイン にデプロイできます。サブドメインやドメインを設定していない場合、Wrangler はデプロイ中にセットアップを求めます。
npx wrangler deploy<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev で Worker をプレビューします。
これらの手順を完了すると、基本的な Rust 製 Worker がデプロイされます。ここから依存関係を追加し、Rust でコードを書いて Worker アプリケーションを実装できます。Rust からコンパイルした Wasm が Workers でどのようにサポートされているかを知りたい場合は、次のセクションで関連するライブラリとツールを説明します。
Wasm Worker は、workers-rs を使うと自動生成される JavaScript エントリポイントスクリプトから呼び出されます。
バインディングなどのプラットフォーム機能にアクセスするには、Wasm Worker が JavaScript Runtime API のメソッドにアクセスできる必要があります。
この相互運用は wasm-bindgen ↗ で実現します。Runtime API を Wasm モジュールにインポートし、イベントハンドラーをエクスポートするために必要な橋渡しコードを提供します。wasm-bindgen は js-sys ↗ も提供し、JavaScript オブジェクトとやり取りするための型を実装します。実務上は実装の詳細です。workers-rs の API が、JavaScript オブジェクトとの変換と、インポートした JavaScript Runtime API とのやり取りを処理します。
wasm-bindgen-futures ↗(wasm-bindgen プロジェクトの一部)は、Rust の Future と JavaScript の Promise の相互運用を提供します。workers-rs はイベントハンドラー関数全体を spawn_local で呼び出すため、async Rust でプログラムでき、それが 1 つの JavaScript Promise に変換されて JavaScript のイベントループ上で実行されます。インポートした JavaScript Runtime API への呼び出しは、自動的に Rust Future に変換され、async の Rust 関数から呼び出せます。
結果の Wasm バイナリを Workers 上で実行するために、workers-rs には worker-build ↗ というビルドツールが含まれます。このツールは次を行います。
wasm-bindgenの JavaScript API でモジュールを正しく呼び出す JavaScript エントリポイントスクリプトを作成します。web-packを呼び出して、JavaScript コードを圧縮・バンドルします。- Wrangler が最終的な Worker をバンドルしてデプロイできるディレクトリ構造を出力します。
worker-build は、テンプレートプロジェクトでは wrangler.toml に指定したカスタムビルドコマンドでデフォルト実行されます。
最適化していない Rust Wasm バイナリは大きく、Worker のバンドルサイズ制限を超えることや、起動が遅くなることがあります。テンプレートプロジェクトは、Cargo.toml にいくつかの有用なサイズ最適化をあらかじめ設定しています。
[profile.release]
lto = true
strip = true
codegen-units = 1最後に、worker-bundle はアップロード前に wasm-opt ↗ を自動実行し、バイナリサイズをさらに最適化します。