🚀

Rocket.rs + Shuttleでテンプレートを使う

2023/08/11に公開

概要

Rust製WebフレームワークのRocketで作ったWebアプリをShuttleにデプロイする際、テンプレートの扱いで若干ハマったのでメモ。
Rust初学者なので間違いがあるかもしれませんがご容赦ください。

バージョン

rocket = { version = "=0.5.0-rc.3" }
rocket_dyn_templates = { version = "=0.1.0-rc.3", features = ["tera"] }
shuttle-rocket = "0.23.0"
shuttle-runtime = "0.23.0"
shuttle-static-folder = "0.23.0"

元コード

#[shuttle_runtime::main]
async fn rocket() -> shuttle_rocket::ShuttleRocket {
    let rocket = rocket::build()
        .mount("/", routes![test])
        .mount("/assets", FileServer::from(relative!("assets")))
        .attach(Template::fairing());
    Ok(rocket.into())
}

assets/フォルダに画像を、templates/フォルダにテンプレートファイルを配置していたが、Shuttleはデフォルトではstaticなファイルをdeployしないので、このままcargo shuttle deployするとtemplatesフォルダがない、と怒られます。

修正

assets/フォルダの転送

#[shuttle_runtime::main]
- async fn rocket() -> shuttle_rocket::ShuttleRocket {
+ async fn rocket(
+     #[shuttle_static_folder::StaticFolder(folder = "assets")] static_folder: PathBuf,
+ ) -> shuttle_rocket::ShuttleRocket {
    let rocket = rocket::build()
        .mount("/", routes![test])
-         .mount("/assets", FileServer::from(relative!("assets")))
+         .mount("/assets", FileServer::from(static_folder))
        .attach(Template::fairing());
    Ok(rocket.into())
}

#[shuttle_static_folder::StaticFolder]マクロを付与した引数を指定することで、Shuttleにstaticファイルを格納したフォルダをdeployすることができます。デフォルトではstaticという名前のフォルダがdeployされるので、必要に応じてfolderを指定する必要があります。
https://docs.shuttle.rs/resources/shuttle-static-folder

templates/フォルダの転送

#[shuttle_runtime::main]
async fn rocket(
    #[shuttle_static_folder::StaticFolder(folder = "assets")] static_folder: PathBuf,
+     #[shuttle_static_folder::StaticFolder(folder = "templates")] template_folder: PathBuf,
) -> shuttle_rocket::ShuttleRocket {
-     let rocket = rocket::build()
+     let figment = rocket::Config::figment().merge(("template_dir", template_folder));
+     let rocket = rocket::custom(figment)
        .mount("/", routes![test])
        .mount("/assets", FileServer::from(static_folder))
        .attach(Template::fairing());
    Ok(rocket.into())
}

assets/の転送と同様に、#[shuttle_static_folder::StaticFolder]マクロを用いたいのですが、マクロを付与したtemplate_foldertemplate_dirとして宣言する必要があります。
これはRocketのConfigのCustom Providersとして改めて登録し直せばうまくdeployしてくれます。
https://rocket.rs/v0.5-rc/guide/configuration/#custom-providers

おわりに

RocketもShuttleも情報が少ないライブラリ・サービスなので、もし似たようなところで困っている人がいれば参考になるかなと思い投稿しました。
もっといいやり方等あればコメント等でご教示ください。よろしくお願いします。

Discussion