手動でCloudflare WorkersにRust製APIサーバーを立ち上げる

特に理由はないけれど、cargo generateコマンドを使わずにCloudflare WorkersにRust製APIサーバーを立ち上げる手順を探し求めてみたいと思います。

あえて理由をいえば、勉強のためです。

では、はじめてみます。

# Cargo作成

```
cargo new our-wonderful-axum-world
cd our-wonderful-axum-world
```

Cargoはコマンドでつくり、以降は動作するテンプレートと比較したり、エラー文を手がかりとして、必要最小限の記述を読み出していきます。


モデルになるのは以下のコマンドで生成できるテンプレートです。
```
 cargo generate cloudflare/workers-rs
```

https://github.com/cloudflare/workers-rs

# wrangler.toml作成

まずは`npx wrangler dev`だけを実行するとエントリーポイントがないと言われます。

```
X [ERROR] Missing entry-point: The entry-point should be specified via the command line (e.g. `wrangler dev path/to/script`) or the `main` config field.
```


モデルを確認して、`wrangler.toml`を作成して、以下を真似して記載します。

```wrangler.toml
main = "build/worker/shim.mjs"
```

エラー文が以下の通り変わりました。

```
X [ERROR] The entry-point file at "build\worker\shim.mjs" was not found.
```

build成果物が存在しないのかな。

モデルの`wrangler.toml`にある以下の記載が怪しいので、コピペします。

```
[build]
command = "cargo install -q worker-build && worker-build --release"
```

また、エラー文が変わりました。
想定通り、`npx wrangler dev`で記載したcommandが実行されているようです。

```
X [ERROR] Running custom build `cargo install -q worker-build && worker-build --release` failed. There are likely more logs from your build command above.  
```

ログファイルにもっと情報があるよと言われましたが、特にそれっぽい記述が書かれていないため、ビルドコマンドを単体で実行してみます。

```
> worker-build --release
```

すると、以下の通り、ライブラリ化しろって言ってました。
```
Error: crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:

[lib]
crate-type = ["cdylib", "rlib"]
```

これにともない、`main.rs`を`lib.rs`へファイル名を変更し、不要になったmain関数の記述を削除します。

```
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
   Compiling our-wonderful-axum-world v0.1.0 (E:\github\mytool\rust\our-wonderful-axum-world)
    Finished `release` profile [optimized] target(s) in 0.26s
Error: Ensure that you have "wasm-bindgen" as a dependency in your Cargo.toml file:
[dependencies]
wasm-bindgen = "0.2"
```

こう書いてあるので、dependenciesを記述し始めます。

これで、エントリーポイントであるファイルが生成されました。

```
（略）
   Compiling our-wonderful-axum-world v0.1.0 (E:\github\mytool\rust\our-wonderful-axum-world)
    Finished `release` profile [optimized] target(s) in 11.94s
[INFO]: Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
[INFO]: :-) Done in 12.45s
[INFO]: :-) Your wasm pkg is ready to publish at E:\github\mytool\rust\our-wonderful-axum-world\build.

  shim.mjs  1.0kb

Done in 6ms
```

`npx wrangler dev`コマンドを再度実行します。

ようやく、workersアプリが立ちあがりました。

```
[wrangler:inf] Ready on http://127.0.0.1:8787
╭───────────────────────────╮
│  [b] open a browser       │
│  [d] open devtools        │
│  [l] turn off local mode  │
│  [c] clear console        │
│  [x] to exit              │
╰───────────────────────────╯
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
    Finished `release` profile [optimized] target(s) in 0.05s
[INFO]: Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
⎔ Starting local server...
╭───────────────────────────╮
│  [b] open a browser       │
│  [d] open devtools        │
│  [l] turn off local mode  │
│  [c] clear console        │
│  [x] to exit              │
╰───────────────────────────╯
```

このまま`http://127.0.0.1:8787`へアクセスすると、エラー表示されます。
サーバーそのものの処理を実装していないため、当然ですね。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821654/c9670e13-0b08-23fe-d8de-e4e8a55f2feb.png)

CloudflareのドキュメントにWorkersのコードの書き方があるので、これを参考にします。

https://developers.cloudflare.com/workers/languages/rust/#3-write-your-worker-code

```diff:wrangler.toml
+ worker = "0.5.0"
```

```rust:lib.rs
use worker::*;

#[event(fetch)]
async fn main(req: Request, env: Env, ctx: Context) -> Result<Response> {
    Response::ok("Hello, World!")
}
```

これで、GETリクエストに対して「Hello, World!」を返すようになりました。

どうやら、これが最小限の構成のようです。

ようやくたどりつきました。

# 終わりに

長ったらしい試行錯誤を繰り返して、なんとか求めていた結果を得ることができました。

RustやCloudflare Workersについて詳しい方であれば、もっと簡単にたどりつくのかもしれないですが、素人には中々歯ごたえがありました。

今後、この経験が直接役立つことはないかもしれませんが、順番にエラー文を追って対処していったことで多少経験値はたまったような気がします。たぶん。

特に教訓もない記事ですので、以上で終わります。

ここまで読んでいただきありがとうございました。