[Rustのはじめ方] Part32: 簡易Webサーバの構築(actix, rocketなど)

Rust

おめでとうございます!🥳 Rust学習の旅もいよいよ最終ステップ、ミニプロジェクトです!これまで学んだ知識を活かして、実際に動くアプリケーションを作ってみましょう。

このセクションでは、Rustで人気のWebフレームワークである Actix WebRocket を使って、簡単なWebサーバーを構築する方法を学びます。Webサーバーは、インターネット上で情報を送受信するための基本的な仕組みです。これを作れるようになると、Webアプリケーション開発の世界がぐっと広がりますよ!

どちらのフレームワークもそれぞれ特徴があります。一緒に見ていきましょう!🚀

Actix Web で作る高速Webサーバー

Actix Webは、非常に高速非同期処理に強いWebフレームワークです。アクターモデルという仕組みをベースにしており、多くのリクエストを効率的にさばくことができます。パフォーマンスが求められるWebサービス開発で人気があります。

1. セットアップ

まずは、プロジェクトに Actix Web を追加しましょう。Cargo.toml ファイルを開き、[dependencies] セクションに以下の行を追加します。バージョンは最新のものを crates.io で確認してくださいね。

[dependencies]
actix-web = "4" # 例: バージョン4系を指定

次に、非同期ランタイムとして tokio も必要になることが多いので、これも追加しておくと良いでしょう。(Actix Web v4以降は `actix_rt` ではなく `tokio` を使うのが一般的です)

[dependencies]
actix-web = "4"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

ファイルに追加したら、cargo build を実行して依存関係をダウンロード・コンパイルします。

2. Hello, World! サーバー

それでは、src/main.rs に簡単なWebサーバーを書いてみましょう。指定したアドレス(例: 127.0.0.1:8080)にアクセスすると “Hello, world!” と表示するだけのシンプルなサーバーです。

use actix_web::{get, web, App, HttpServer, Responder};

#[get("/")] // GETリクエストで "/" にアクセスされた時のハンドラ
async fn hello() -> impl Responder {
    "Hello, world! from Actix Web! 👋" // レスポンスとして返す文字列
}

#[tokio::main] // Tokioランタイムで非同期関数を実行
async fn main() -> std::io::Result<()> {
    println!("🚀 Server starting at http://127.0.0.1:8080");

    HttpServer::new(|| {
        // App::new() でアプリケーションを作成し、サービス(ハンドラ)を登録
        App::new().service(hello)
    })
    .bind(("127.0.0.1", 8080))? // サーバーをIPアドレスとポートにバインド
    .run() // サーバーを実行
    .await // 非同期処理の完了を待つ
}

このコードを書いて cargo run を実行し、Webブラウザや curl コマンドで http://127.0.0.1:8080 にアクセスしてみてください。”Hello, world! from Actix Web! 👋” と表示されれば成功です!🎉

3. ルーティングとハンドラ

Actix Webでは、#[get("/path")]#[post("/path")] のようなアトリビュートマクロを使って、特定のパスとHTTPメソッドに対する処理(ハンドラ関数)を結びつけます。

ハンドラ関数は非同期関数 (async fn) として定義し、Responder トレイトを実装した型(文字列、JSON、HTTPレスポンスなど)を返します。

例えば、パスパラメータを受け取る場合は次のように書けます。

use actix_web::{get, web, App, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    "Hello, world! from Actix Web! 👋"
}

// `/hello/{name}` というパスに対応するハンドラ
#[get("/hello/{name}")]
async fn greet(name: web::Path<String>) -> impl Responder {
    format!("Hello, {}!", name) // パスから受け取ったnameを使って挨拶
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    println!("🚀 Server starting at http://127.0.0.1:8080");

    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(greet) // greetハンドラも登録
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

これで、http://127.0.0.1:8080/hello/Rustacean にアクセスすると “Hello, Rustacean!” と表示されるようになります。

Actix Webには他にも、リクエストボディの取得、JSONの送受信、ミドルウェア、状態管理など、Webアプリケーション開発に必要な機能がたくさん用意されています。詳しくは Actix Webの公式ドキュメント を参照してください。

Rocket で作る安全で簡単なWebサーバー

Rocketは、使いやすさ型安全性に重点を置いたWebフレームワークです。Rustの強力な型システムを活用し、コンパイル時にエラーを発見しやすくしています。コードが直感的で書きやすいと評判です。

注意: Rocketは歴史的にNightly版のRustコンパイラを必要とすることがありましたが、最近のバージョン (0.5以降) では Stable版のRustでも動作するようになっています!最新の情報を Rocket公式サイト で確認しましょう。

1. セットアップ

Rocketを使うために、Cargo.toml に依存関係を追加します。バージョンは crates.io で確認してください。JSONを扱う機能なども必要に応じて `features` で有効にします。

[dependencies]
rocket = { version = "0.5", features = ["json"] } # 例: バージョン0.5系、JSON機能付き

ファイルに追加したら、cargo build を実行します。

2. Hello, World! サーバー

Rocketでも簡単な “Hello, world!” サーバーを作ってみましょう。src/main.rs を以下のように編集します。

#[macro_use] extern crate rocket; // Rocketのマクロを有効化

#[get("/")] // GETリクエストで "/" にアクセスされた時のハンドラ (ルート)
fn index() -> &'static str { // &'static str は静的な文字列スライス
    "Hello, world! from Rocket! 🚀"
}

#[launch] // main関数の代わりにRocketの起動ポイントを示すマクロ
fn rocket() -> _ { // `_` は型推論に任せることを示す
    println!("🚀 Server starting with Rocket!");
    rocket::build().mount("/", routes![index]) // ルート "/" に index ハンドラをマウント
}

Actix Webと似ていますが、いくつか特徴があります。

  • #[macro_use] extern crate rocket; でRocketのマクロを使えるようにします。
  • #[get("/")] アトリビュートでルーティングを定義します(Actix Webと同様)。
  • ハンドラ関数 (index) は非同期 (async) である必要はありません(非同期も可能)。
  • #[launch] マクロがプログラムのエントリーポイントとなり、サーバーを起動します。main 関数は使いません。
  • rocket::build().mount("/", routes![index]) で、指定したパス (/) にハンドラ (index) を登録(マウント)します。routes! マクロで複数のルートをまとめることができます。

cargo run で実行し、http://127.0.0.1:8000 (Rocketのデフォルトポート) にアクセスすると “Hello, world! from Rocket! 🚀” と表示されるはずです。

3. ルーティングとハンドラ

Rocketのルーティングもアトリビュートマクロ (#[get], #[post] など) を使います。パスパラメータの受け取りも直感的です。

#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello, world! from Rocket! 🚀"
}

// `/hello/` というパスに対応
// <name> の部分がハンドラの引数 name に束縛される
#[get("/hello/<name>")]
fn greet(name: &str) -> String { // &str で文字列スライスを受け取る
    format!("Hello, {}!", name) // String型を返す
}

#[launch]
fn rocket() -> _ {
    println!("🚀 Server starting with Rocket!");
    rocket::build().mount("/", routes![index, greet]) // greetルートも追加
}

これで http://127.0.0.1:8000/hello/RustFan にアクセスすると “Hello, RustFan!” と表示されます。Rocketは型チェックが厳密で、例えば #[get("/user/<id>")] fn user(id: u32) のように書くと、パスの <id> 部分が自動的に u32 型に変換できない場合はリクエストが拒否され、ハンドラは実行されません。これにより、予期しない入力に対する安全性が高まります。

Rocketには、リクエストガード、フォーム処理、テンプレートエンジン連携、状態管理など、モダンなWeb開発に必要な機能が揃っています。詳細は Rocketの公式ガイド を確認してみてください。

Actix Web vs Rocket: どちらを選ぶ? 🤔

Actix WebとRocketはどちらも素晴らしいフレームワークですが、それぞれ得意なことや特徴が異なります。どちらを選ぶかは、プロジェクトの要件やあなたの好みによります。

特徴 Actix Web Rocket
パフォーマンス 非常に高速。非同期処理とアクターモデルにより高負荷に強い。ベンチマークで常に上位。 十分高速。型安全性や使いやすさとのバランスが良い。
安定性・エコシステム 成熟しており、多くの本番環境で利用実績がある。関連クレートも豊富。 開発が活発。v0.5でStable対応し、安定性が向上。エコシステムも成長中。
非同期処理 ネイティブに非同期(async/await)を前提とする。 非同期ハンドラもサポートしているが、同期ハンドラも書きやすい。
学習コスト・使いやすさ アクターモデルや非同期の概念に慣れが必要な場合がある。機能が豊富。 直感的で書きやすいAPI。型安全性が高く、コンパイル時エラーで間違いに気づきやすい。ドキュメントも丁寧。
コンパイル 比較的安定。 マクロを多用するため、コンパイル時間が長くなる傾向がある。以前はNightly Rustが必要だったが、Stable版でも利用可能に。

簡単なまとめ:

  • 最高のパフォーマンスが欲しい、非同期処理を深く理解したい → Actix Web
  • 開発のしやすさ、型安全性、直感的なAPIが好み → Rocket

まずは両方のフレームワークで簡単なサーバーを作ってみて、感触を確かめるのが一番です!✨

まとめと次のステップ

このセクションでは、Actix WebとRocketという2つの人気Rust Webフレームワークを使って、簡単なWebサーバーを構築する方法を学びました。どちらのフレームワークも、Rustの強力な機能を活かして、安全で効率的なWebアプリケーション開発を可能にします。

Webサーバーが作れるようになると、Web APIを実装したり、動的なWebページを生成したりと、作れるものの幅が大きく広がります。今回学んだことをベースに、次のステップに進んでみましょう!

次のステップ候補 JSON APIとの連携とシリアライズ データベースとの接続 認証機能の実装 テンプレートエンジンを使ったHTML生成

これでRust学習サイトの主要なステップは完了です!本当にお疲れ様でした!🍵 これからもRustの世界を探求し、素晴らしいソフトウェアを作り続けてくださいね! Happy Coding! 🎉

コメント

タイトルとURLをコピーしました