Rustでのバックエンド開発、どのフレームワーク?
Rustでバックエンドを書くなら、選択肢は主に3つです:
- Actix-web: 最速だが、独自の
Actorモデルで癖が強い - Rocket: シンプルだが、非同期対応が遅れていた
- Axum: Tokioネイティブで、エルゴノミクスと性能を両立
Tokio/Towerのエコシステムに慣れているなら、Axumは最良の選択です。
ベストマッチ
最短で課題解決する一冊
この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。
Axumの特徴
1. Towerミドルウェアとの完璧な統合
Axumはtowerとtower-httpのミドルウェアがそのまま使えます。
use axum::{Router, routing::get};
use tower::ServiceBuilder;
use tower_http::{trace::TraceLayer, compression::CompressionLayer};
use std::time::Duration;
let app = Router::new()
.route("/", get(|| async { "Hello!" }))
.layer(
ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new())
.timeout(Duration::from_secs(10))
);2. エクストラクタパターン
リクエストからのデータ抽出が、型安全かつ宣言的です。
use axum::{
extract::{Path, Query, Json},
http::StatusCode,
};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Pagination {
page: Option<u32>,
limit: Option<u32>,
}
#[derive(Serialize)]
struct User {
id: u32,
name: String,
}
async fn get_user(
Path(user_id): Path<u32>,
Query(pagination): Query<Pagination>,
) -> Result<Json<User>, StatusCode> {
// idやpaginationが既に型付けされた状態で使える
Ok(Json(User {
id: user_id,
name: "Alice".to_string(),
}))
}さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
実践:JWT認証付きREST API構築
実用的なCRUD APIを、認証込みで実装してみましょう。
プロジェクトセットアップ
# Cargo.toml
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
tower = "0.4"
tower-http = { version = "0.5", features = ["trace", "cors"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
jsonwebtoken = "9"
tracing = "0.1"
tracing-subscriber = "0.3"
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }JWT認証ミドルウェア
use axum::{
async_trait,
extract::{FromRequestParts, TypedHeader},
headers::{Authorization, authorization::Bearer},
http::{request::Parts, StatusCode},
RequestPartsExt,
};
use jsonwebtoken::{decode, DecodingKey, Validation};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
}
struct AuthUser(Claims);
#[async_trait]
impl<S> FromRequestParts<S> for AuthUser
where
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>()
.await
.map_err(|_| StatusCode::UNAUTHORIZED)?;
let token_data = decode::<Claims>(
bearer.token(),
&DecodingKey::from_secret("secret".as_ref()),
&Validation::default(),
)
.map_err(|_| StatusCode::UNAUTHORIZED)?;
Ok(AuthUser(token_data.claims))
}
}APIハンドラー
use axum::{
extract::State,
routing::{get, post},
Json, Router,
};
#[derive(Clone)]
struct AppState {
db: sqlx::PgPool,
}
// 認証不要
async fn health_check() -> &'static str {
"OK"
}
// 認証必須
async fn get_profile(
AuthUser(claims): AuthUser,
State(state): State<AppState>,
) -> Result<Json<User>, StatusCode> {
let user = sqlx::query_as::<_, User>(
"SELECT id, name FROM users WHERE id = $1"
)
.bind(&claims.sub)
.fetch_one(&state.db)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(Json(user))
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let db = sqlx::postgres::PgPoolOptions::new()
.max_connections(5)
.connect("postgresql://localhost/mydb")
.await
.unwrap();
let state = AppState { db };
let app = Router::new()
.route("/health", get(health_check))
.route("/profile", get(get_profile))
.with_state(state);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}パフォーマンス最適化
1. 非同期処理の注意点
use tokio::task;
// ❌ CPU集約的な処理をそのまま実行(Tokioランタイムをブロック)
async fn bad_handler() -> String {
let result = expensive_computation(); // NG!
result
}
// ✅ spawn_blockingでブロッキング処理を分離
async fn good_handler() -> String {
task::spawn_blocking(|| expensive_computation())
.await
.unwrap()
}2. データベース接続プール
// 接続数を適切に設定
let pool = sqlx::postgres::PgPoolOptions::new()
.max_connections(50)
.min_connections(5)
.acquire_timeout(Duration::from_secs(3))
.connect("postgresql://localhost/mydb")
.await?;さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
まとめ
Axumは、Rustの型システムとTokioのエコシステムを最大限活用した、モダンなWebフレームワークです。
Actix-webの速度に近く、Rocketのエルゴノミクスを持ち、Towerの柔軟性を完全に統合しています。
Tokio/async Rustに慣れているなら、Axumで快適なバックエンド開発を体験してみませんか?
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
この記事をシェア



![Pythonクローリング&スクレイピング[増補改訂版] -データ収集・解析のための実践開発ガイド-](https://m.media-amazon.com/images/I/41M0fHtnwxL._SL500_.jpg)
