@now/rustを使ったサーバーレスコンピューティング

準備

まずシステムを汚染しないようにnowをインストール:

npm config set prefix ~/.local/npm/
npm install -g now
ln -s ~/.local/npm/bin/now `/.local/bin/now

試行

紹介ポスト(dead link https://zeit.co/blog/introducing-now-rust)は色々と内容が古くなっているので Document(dead link https://zeit.co/docs/v2/deployments/official-builders/now-rust/)をたどる方がよい。

Tips

要求: $TOP/index.rsではなくsrc/の下においてcargoでコンパイルしたい。

now.jsonでビルド元を指定すればよい。

    "builds": [
	{
	    "src": "src/index.rs",
	    "use": "@now/rust"
	}
    ],

ただし、これだけだとendpointの対応が取れなくなるのでroutesも指定する。

    "routes": [
	{
	    "src": "/",
	    "dest": "/src/"
	}
    ]

要求:手元でも実行できるようにして、ソースを変えずにデプロイしたい

デプロイするのはsrc/index.rsなので、それ以外のソースにmain関数があればいい。 実行ファイルを生成するためのファイルは.nowignoreで隠してしまえばよい。

/target
/src/bin
...

そもそも、デプロイ時にはhandler関数を提供するRustライブラリパッケージという位置付けのようだ。 なのでそこに実行ファイルを置きたいならsrc/binの下のファイルをcargo run -binで実行しろと いう話。

要求:手元で実行するための依存パッケージをデプロイ先でコンパイルしたくない

cargoのfeatureを使えばいい

# Cargo.toml

[dependencies]
http = "0.1"
regex = "1.1.0"
reqwest = { version = "0.9.12", optional = true }
scraper = { version = "0.9.2", optional = true }
serde = { version = "1.0.89", features = ["derive"] }
serde_json = "1.0"
url = { version = "1.7.2", features = [ "query_encoding" ] }

[features]
prepare = ["reqwest", "scraper"]

こうしておいて、手元で実行するときは以下を実行。

cargo run --bin xxx --features prepare

デプロイ時にはfeaturesは指定されないので依存パッケージも取得、コンパイルされない。

要求:handlerを手元で実行する時も流用したい

handlerの型は

fn handler(request: http::Request<()>) -> http::Result<http::Response<String>>;

なのでこれと同じであればいいのだが、例えばactix-webではRequsetなどを自前で定義しているので 難しそうだ。traitオブジェクト的にコンパチかもしれないが。。。

まあ、htmlを返す下請け関数を作ってどちらからもこの関数を使うというあたりが落とし所か。