Day16 Rustで動的Webサーバーを作るなら?
動的って言ってますがなんかまぁ動的…なのかな…? APIみたいな…うーん…
use axum::{Router, serve};
use tokio::net::TcpListener;
#[cfg(debug_assertions)]
use axum_reverse_proxy::ReverseProxy;
#[cfg(not(debug_assertions))]
use tower_http::services::ServeDir;
#[tokio::main]
async fn main() {
#[cfg(debug_assertions)]
let app = async {
loop {
let resp = reqwest::get("http://localhost:5173").await;
if resp.is_ok() {
break;
}
tokio::time::sleep(std::time::Duration::from_millis(2000)).await;
}
Router::new()
.nest("/api", api_router(state))
.merge(ReverseProxy::new("/", "http://localhost:5173"))
}
.await;
#[cfg(not(debug_assertions))]
let app = {
let vite_dist_dir = ServeDir::new("dist");
Router::new()
.nest("/api", api_router(state))
.fallback_service(vite_dist_dir)
};
let listener: TcpListener = TcpListener::bind("0.0.0.0:8080").await.unwrap();
serve(listener, app).await.unwrap();
}
(既存のコードを切り貼りしてるから動かないかもしれない)
さて,このコードを見ることで…なんとなく何がやりたいか分るでしょうか.
…そうですね! あのViteとコラボしていそうですね!
Viteは以前にも紹介したフロントエンドのやつです.
フロントエンドをVite,そしてバックエンドをRustで書けたら,みんな最高なんじゃないんですか!?
という訳で,APIサーバー的なものを立てるならこうするのが理想形でしょう.
YewというようなRustで生にHTMLを書けるものがあったと思いますが,あれはWASMを使ってフロントエンド側でRustを動かしており,そういう訳ではないのでちょっと違ったアプローチにはなりますね
なぜ今回これを紹介したかったかというと,このようなコードを使用したプロジェクト開発を直近で行っていて,Rustの学習としてRustも使いたいけどフロントエンドは書きなれたやつでやりたいなっていう欲望によって生まれたこの造物をみんなに知って欲しかったから.うん.
これをやって驚いたこと
起動があまりにも早すぎる.
productionの方のコード (フロントエンドはビルド済み) で実行したんですけど,なんかあまりにも起動が早い.
Pythonでaiohttpとか使ってサーバー立てた時って起動までn秒ぐらいかかってたイメージなのに,このサーバープログラムを実行したらなんかガチ遅延なしぐらいで起動しちゃって.ヒエー
まぁ多分これはインタプリタvsコンパイルの違いとかなんでしょうね.
という訳であなたも
Rustをバックエンドに採用したサーバーを作るなら,Viteを使ってリバースプロキシや,ServeDirのstaticDirを使ってみてはいかがでしょうか.