[WASM] イベント駆動型フレームワーク Spin
Introduction
先日はWasmtime(WASMランタイム)を紹介しましたが、
今回はSpinという名前の、
WebAssemblyを使用するイベント駆動型フレームワークについて紹介します。
SpinはWebアプリ用のフレームワークで、
HTTPリクエストに対してレスポンスを返すWASMモジュールを
作成するためのインターフェイスを提供します。
現状、RustとGoがサポートされていますが、
WASMで動くのでPythonやAssemblyScript、C/C ++などでも作成可能とのことです。
Spinでは、「Httpトリガー」と「Redisトリガー」という2つのタイプの
アプリを作成することができます。
Httpトリガーは要するにWebサーバーです。
アプリの定義(URL)に基づいて、適切なWASMコンポーネントにルーティングし、
HTTPのリクエスト/レスポンスを行います。
Redisトリガーは、
任意のRedisチャンネルに対するメッセージによって
SpinのWASMコンポーネントを起動することができるタイプのアプリです。
今回はここにある、
Httpトリガータイプのサンプルプロジェクトを作成してみましょう。
Environment
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 11.3.1
- rust : 1.61.0
Setup
Spinを使うには、Githubからダウンロードしてきます。
下記のようにダウンロード&解凍してspinコマンドが実行できれば大丈夫です。
% mkdir spin && cd spin % curl -L https://github.com/fermyon/spin/releases/download/v0.2.0/spin-v0.2.0-macos-aarch64.tar.gz > spin-v0.2.0-macos-aarch64.tar.gz % tar xfv spin-v0.2.0-macos-aarch64.tar.gz % ./spin --help spin 0.2.0 (4ff1c75 2022-05-12) The Spin CLI
Try
では、Spinの提供するテンプレートから新しいアプリを作成していきます。
% spin templates list You have no templates installed. Run spin templates install --git https://github.com/fermyon/spin to install a starter set.
まず、Spinリポジトリからテンプレートを構成する必要があります。
template installで現在提供されているテンプレートを取得。
% spin templates install --git https://github.com/fermyon/spin --branch v0.2.0 Copying remote template source Installing template redis-rust... Installing template http-rust... Installing template http-go... Installing template redis-go... Installed 4 template(s) ・・・
template listで現在使用可能なテンプレートが表示されます。
GoとRustのHttp/Redisトリガータイプのテンプレートがあります。
% spin templates list +---------------------------------------------------+ | Name Description | +===================================================+ | http-go HTTP request handler using (Tiny)Go | | http-rust HTTP request handler using Rust | | redis-go Redis message handler using (Tiny)Go | | redis-rust Redis message handler using Rust | +---------------------------------------------------+
ではRustのHttpテンプレートタイプでアプリの雛形をつくります。
プロジェクト名とかURLのbase、パスをきめて作成。
% spin new http-rust Project description: spin http project Project name: spin-http HTTP base: / HTTP path: hello Invalid value: Input 'hello' does not match pattern '^/\S*$' #正しいパスじゃないと怒られる HTTP path: /hello
これで最低限必要なファイルはすべて生成されました。
spinアプリはアプリの定義ファイル「spin.toml」と
1つ以上のWASMコンポーネントから構成されます。
spin.tomlは、下記のようなマニフェストファイルになっています。
spin_version = "1" authors = ["shuta nakamura"] description = "spin http project" name = "spin-http" trigger = { type = "http", base = "/" } version = "0.1.0" [[component]] id = "spin-http" source = "target/wasm32-wasi/release/spin_http.wasm" [component.trigger] route = "/hello" [component.build] command = "cargo build --target wasm32-wasi --release"
Httpリクエストをトリガーとするアプリであることを示し、
/helloリクエストに対してWASMモジュール(spin_hello_world.wasm)を
実行することが定義されています。
次にRustで記述されたコンポーネントを見てみます。
↓はsrc/lib.rsのコードです。
http_componentアトリビュートがついており、
これがコンポーネントであることを表しています。
関数自体はリクエストを受け取り、レスポンスを返すシンプルなものです。
use anyhow::Result; use spin_sdk::{ http::{Request, Response}, http_component, }; /// A simple Spin HTTP component. #[http_component] fn spin_http(req: Request) -> Result<Response> { println!("{:?}", req.headers()); Ok(http::Response::builder() .status(200) .header("foo", "bar") .body(Some("Hello, Fermyon".into()))?) }
spin buildコマンドでビルドを行います。
実際はspin.tomlにあるように、cargo buildをwasm32-wasターゲットで実施しています。
% spin build Executing the build command for component spin-http: cargo build --target wasm32-wasi --release Updating crates.io index Updating git repository `https://github.com/fermyon/spin` Updating git repository `https://github.com/bytecodealliance/wit-bindgen` Updating git repository `https://github.com/deislabs/wasi-experimental-http` Updating git repository `https://github.com/bytecodealliance/wit-bindgen` Compiling anyhow v1.0.57 Compiling version_check v0.9.4 ・・・ Finished release [optimized] target(s) in 21.72s Successfully ran the build command for the Spin components.
中身を見ると、build時にwit-bindgenを使って
witやらjsバインディングやらを生成したりして
Rustのwasmを実行できるようにしてるみたいです。
そして、アプリを実行するにはspin upコマンドを叩く。
% spin up Serving HTTP on address http://127.0.0.1:3000 2022-06-02T05:12:36.251490Z INFO spin_http_engine: Serving HTTP on address 127.0.0.1:3000 Available Routes: spin-http: http://127.0.0.1:3000/hello
起動したのでcurlで動作確認してみます。
% curl -i http://localhost:3000/hello HTTP/1.1 200 OK foo: bar content-length: 14 date: Thu, 02 Jun 2022 06:00:02 GMT Hello, Fermyon%
これでシンプルなHttpトリガーのSpinアプリができました。
ちなみに、buildと起動を同時に行うには下記コマンドを実行します。
% spin build --up
Summary
今回はSpinフレームワークのHttpトリガーアプリを動かしてみました。
次回はRedisトリガーのアプリを作ってみようかと思います。