Rustで高速かつ安全なWebアプリケーションを構築したい。そんなとき選択肢に挙がるフレームワークの一つがRocketです。Rocketは「型安全」「ボイラープレート最小化」「直感的なAPI」を設計原則とし、Rustの強みを最大限に活かしたWeb開発体験を提供します。
2023年11月にリリースされたv0.5.0でstable Rust対応と非同期処理の全面採用を実現し、以前の「nightly必須」という制約が撤廃されました。この記事では、Rocketの基本から実践的な導入手順、他のRust製フレームワークとの使い分けまでを具体的に整理します。
Rocketの基本情報と設計思想
RocketはSergio Benitez氏が2016年に開発を開始したRust製Webフレームワークです。2023年11月にはRocket Web Framework Foundation(RWF2)が501(c)(3)非営利団体として発表され、個人依存からコミュニティ主導の開発体制へ移行しています。
| 項目 | 内容 |
|---|---|
| 最新バージョン | v0.5.1(2024年5月リリース) |
| ライセンス | Apache-2.0 / MIT デュアルライセンス |
| 対応Rustバージョン | stable Rust 1.64以上 |
| 非同期ランタイム | Tokio |
| GitHub Stars | 約25,700(2026年2月時点) |
| crates.ioダウンロード数 | 約1,000万回(累計、2026年2月時点) |
| コントリビューター数 | 307名以上 |
| 公式サイト | rocket.rs |
4つの設計原則
Rocketは公式ドキュメントで以下の4つの設計原則を掲げています。
1. 型安全(Security) リクエストデータのバリデーションをコンパイル時に型システムで保証します。不正な型のデータはコンパイルが通らないため、実行時エラーのリスクが大幅に低減されます。
2. ボイラープレート最小化(Boilerplate-Free) ルーティング定義やリクエストパース処理をマクロで自動生成します。開発者はビジネスロジックに集中できます。
3. 直感的なAPI(Easy-to-Use) Ruby on RailsやFlaskのような親しみやすいAPI設計です。Rustの学習コストはあるものの、フレームワーク自体のAPIは最小限の学習で使い始められます。
4. 拡張性(Extensible) Fairings(ミドルウェア相当)やカスタムGuardなど、フレームワークの挙動を柔軟にカスタマイズできる仕組みが用意されています。
v0.5で何が変わったか:2つの大きな転換点
Rocket v0.5.0(2023年11月リリース)はフレームワーク史上最大のアップデートです。v0.4以前とは別物と言えるほど変化しています。
転換点1:stable Rustで動作
v0.4まではRustのnightlyツールチェーンが必須でした。nightlyは不安定なコンパイラ機能を使うため、ビルドが突然壊れるリスクがあり、プロダクション採用のハードルになっていました。
v0.5ではRust 2021エディションを採用し、stable Rustでコンパイルできます。最低対応バージョンはRust 1.64です。
# v0.4以前(nightly必須だった)
rustup override set nightly
# v0.5以降(stableで動作する)
rustup default stable
cargo new my-rocket-app
cd my-rocket-app
注意点: 現在でもネット上にはv0.4時代の「nightly必須」という古い情報が多く残っています。v0.5以降ではstableで問題なく動作します。
転換点2:非同期処理の全面採用
v0.4はスレッドベースの同期処理モデルでした。v0.5ではTokioをランタイムとして採用し、ルートハンドラをasync fnで記述できます。
// v0.5の非同期ハンドラ
#[get("/data")]
async fn get_data(db: &State<DbPool>) -> Json<Vec<Item>> {
let items = db.fetch_all().await;
Json(items)
}
同期的なハンドラも引き続きサポートされますが、I/O処理を含む場合はasyncの使用が推奨されています。
その他の主要な変更点
| 機能 | 内容 |
|---|---|
| Sentinels | ルートで使用する型が起動時に自動検証される(例: &State<T>が未登録なら起動失敗) |
| WebSocket対応 | rocket_wsクレートによるWebSocketサポート |
| SSE(Server-Sent Events) | EventStream型によるリアルタイムストリーミング |
| セキュリティヘッダ | Shield機能で主要なセキュリティヘッダが自動付与 |
| Mutual TLS | クライアント証明書認証のサポート |
| HTTP/2 | ALPN経由で自動対応 |
| Graceful Shutdown | 猶予期間を設定可能なシャットダウン機構 |
| 設定システム刷新 | Figmentベースの設定管理。ROCKET_PROFILE環境変数による切り替え |
v0.4からの移行で注意が必要なAPI変更
// v0.4
rocket::ignite().mount("/", routes![index]).launch();
// v0.5
rocket::build().mount("/", routes![index]).launch();
rocket_contribクレートは廃止され、rocket_dyn_templates、rocket_db_pools、rocket_wsなどの個別クレートに分離されています。
実際の導入手順:Hello Worldから動的ルーティングまで
Step 1:プロジェクト作成とクレート追加
cargo new rocket-demo
cd rocket-demo
Cargo.tomlにRocketを追加します。
[dependencies]
rocket = "0.5.1"
Step 2:最小構成のWebサーバー
src/main.rsを以下のように記述します。
#[macro_use] extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello, Rocket!"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index])
}
#[launch]マクロがエントリーポイントを自動生成し、#[get("/")]がGETリクエストのルーティングを定義します。
cargo run
http://127.0.0.1:8000/ にアクセスすると「Hello, Rocket!」が表示されます。
Step 3:動的ルーティングとパラメータ
パスパラメータは<name>構文で受け取ります。型が一致しないリクエストは自動的に404を返します。
#[get("/user/<id>")]
fn user(id: u32) -> String {
format!("ユーザーID: {}", id)
}
#[get("/greet/<name>")]
fn greet(name: &str) -> String {
format!("こんにちは、{}さん!", name)
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index, user, greet])
}
/user/abcのように数値以外がアクセスされた場合、Rocketは自動で404レスポンスを返します。明示的なバリデーションコードは不要です。
Step 4:JSONレスポンスの実装
REST APIを構築する場合、serdeとrocket::serde::json::Jsonを使います。
[dependencies]
rocket = { version = "0.5.1", features = ["json"] }
serde = { version = "1", features = ["derive"] }
use rocket::serde::{Serialize, json::Json};
#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct Task {
id: u32,
title: String,
completed: bool,
}
#[get("/tasks")]
fn tasks() -> Json<Vec<Task>> {
Json(vec![
Task { id: 1, title: "Rocketを学ぶ".into(), completed: false },
Task { id: 2, title: "APIを実装する".into(), completed: true },
])
}
Step 5:POSTリクエストとデータ受信
use rocket::serde::{Deserialize, json::Json};
#[derive(Deserialize)]
#[serde(crate = "rocket::serde")]
struct NewTask {
title: String,
}
#[post("/tasks", data = "<task>")]
fn create_task(task: Json<NewTask>) -> Json<Task> {
Json(Task {
id: 3,
title: task.title.clone(),
completed: false,
})
}
data = "<task>"でリクエストボディの変数名を指定し、Json<NewTask>型でデシリアライズを自動処理します。
Fairings:リクエストのライフサイクルに介入する
Fairingsは他のフレームワークにおけるミドルウェアに相当する仕組みです。リクエストの処理前後やレスポンス送信前にカスタム処理を差し込めます。
use rocket::fairing::{Fairing, Info, Kind};
use rocket::{Request, Response};
pub struct RequestTimer;
#[rocket::async_trait]
impl Fairing for RequestTimer {
fn info(&self) -> Info {
Info {
name: "Request Timer",
kind: Kind::Request | Kind::Response,
}
}
async fn on_request(&self, req: &mut Request<'_>, _: &mut rocket::Data<'_>) {
println!("リクエスト受信: {} {}", req.method(), req.uri());
}
async fn on_response<'r>(&self, _req: &'r Request<'_>, res: &mut Response<'r>) {
res.set_header(rocket::http::Header::new("X-Custom-Header", "Rocket"));
}
}
Fairingの登録はattachメソッドで行います。
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(RequestTimer)
.mount("/", routes![index])
}
CORS設定やログ記録、認証チェックなど、横断的な処理をFairingsで一元管理できます。
テスト:組み込みのテストライブラリ
Rocketにはテスト用のClientが組み込まれています。実際にHTTPサーバーを起動せずにハンドラの動作を検証できます。
#[cfg(test)]
mod tests {
use super::*;
use rocket::local::blocking::Client;
use rocket::http::Status;
#[test]
fn test_index() {
let client = Client::tracked(rocket()).expect("valid rocket");
let response = client.get("/").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "Hello, Rocket!");
}
#[test]
fn test_user_not_found() {
let client = Client::tracked(rocket()).expect("valid rocket");
let response = client.get("/user/abc").dispatch();
assert_eq!(response.status(), Status::NotFound);
}
}
非同期テストにはrocket::local::asynchronous::Clientを使用します。
Axum・Actix-webとの比較:選定基準の整理
Rust製Webフレームワークは主にRocket、Axum、Actix-webの3つが広く利用されています。それぞれの特性を整理します。
基本情報の比較
| 観点 | Rocket | Axum | Actix-web |
|---|---|---|---|
| 初期リリース | 2016年 | 2021年 | 2017年 |
| 最新バージョン | v0.5.1 | v0.8系 | v4系 |
| GitHub Stars(概算) | 約25,700 | 約24,900 | 約24,300 |
| 被依存プロジェクト数 | 約34,400 | 約77,300 | 約72,500 |
| 非同期ランタイム | Tokio | Tokio | Tokio(独自アクターモデルも利用可) |
| 設計方針 | 高い抽象度・型安全優先 | 薄いレイヤー・Tower互換 | 高パフォーマンス・アクターモデル |
パフォーマンス傾向
ベンチマーク結果はテスト条件によって変動しますが、一般的な傾向として以下が知られています。
- Actix-webが最も高いスループットを記録するケースが多い
- AxumはActix-webに近いパフォーマンスを示し、メモリ効率に優れる
- Rocketは抽象レイヤーのオーバーヘッドにより、上記2つよりやや低い数値になる傾向がある
ただし、多くのWebアプリケーションではデータベースアクセスや外部API呼び出しがボトルネックとなるため、フレームワーク間の性能差が実際の運用に影響するケースは限定的です。
開発体験と学習コストの違い
Rocketが適しているケース:
- Webフレームワーク初学者がRustでサーバーサイド開発を始める場合
- コンパイル時の型チェックによる安全性を最大限に活かしたい場合
- フォームバリデーションやテンプレートレンダリングを多用するフルスタック開発
Axumが適しているケース:
- Tokioエコシステム(tower、hyper、tonic)との統合を重視する場合
- マイクロサービスやgRPCとの併用を想定している場合
- 薄い抽象レイヤーで細かい制御を行いたい場合
Actix-webが適しているケース:
- 低レイテンシが最重要要件のハイパフォーマンスAPI
- アクターモデルによる並行処理パターンを活用したい場合
- WebSocket中心のリアルタイムアプリケーション
選定フローチャート
Rustでの開発経験
├─ 少ない → Rocket(学習コストが比較的低い)
├─ ある程度ある
│ ├─ Tokioを既に使用 → Axum(エコシステムと自然に統合)
│ ├─ 最高性能が必要 → Actix-web(ベンチマーク上位)
│ └─ 型安全重視 → Rocket(コンパイル時検証が充実)
└─ 豊富
└─ 要件に応じて選択(いずれも本番運用実績あり)
Rocketの現在と今後の展望
開発体制の変化
2023年11月にRocket Web Framework Foundation(RWF2)の設立が発表されました。これは開発がSergio Benitez氏個人に依存していた状況を解消し、持続可能なオープンソースプロジェクトとするための施策です。
RWF2は501(c)(3)非営利団体として、以下の活動を行っています。
- フレームワークの開発方針の策定
- uGrants(最大1,000ドルの小規模助成金)による貢献者支援
- コミュニティガバナンスの確立
公式クレート構成
v0.5ではコア機能に加え、公式のコンパニオンクレートが提供されています。
| クレート | 用途 |
|---|---|
rocket | コアフレームワーク |
rocket_db_pools | 非同期データベース接続プール |
rocket_dyn_templates | 動的テンプレート(Handlebars、Minijinja対応) |
rocket_ws | WebSocketサポート |
rocket_sync_db_pools | 同期データベース接続プール(v0.4からの移行用) |
採用を検討する際のチェックリスト
- stable Rust対応を前提に、Rust 1.64以上の環境を用意する
Cargo.tomlでバージョンを0.5.1に固定する- JSON APIが必要な場合は
features = ["json"]を有効化する - テンプレートやDB接続は公式コンパニオンクレートを使用する
- CORSが必要な場合はFairingsで実装するか、
rocket_corsクレートを検討する
まとめ
Rocketは、Rustの型システムを活かした安全なWeb開発体験を重視するフレームワークです。v0.5でstable Rust対応と非同期処理への移行を果たし、以前と比べて導入ハードルが大きく下がりました。
パフォーマンス面ではAxumやActix-webが優位な傾向にありますが、コンパイル時の型検証やボイラープレートの少なさによる開発効率では独自の強みを持っています。Rustでの初めてのWebサーバー構築や、型安全性を最優先する開発においてRocketは有力な選択肢です。
公式サイト(rocket.rs)のガイドやサンプルコードが充実しているため、まずはHello Worldから始めて、段階的にJSON API、データベース接続、テストへと進めるのがスムーズな学習パスです。