RustのWebアプリケーション開発でよく利用するクレートをまとめてみました。
選定方法は、awesome-rustや各リポジトリのスター数などから独断と偏見で記載しています。あくまで個人的な見解なので、「こんなのもあるよ」「ここは違うんじゃないの」などあればお気軽にコメントくださいませ。
Webフレームワーク
Webアプリケーション開発においてWebフレームワークの利用は必須といえるでしょう。現時点ではRustでデファクタとなっているWebフレームワークはないのでactix-web
、rocket
、axum
あたりから選ぶことが多いでしょう。
高機能なactix-web
はまだまだ人気ですが、最近はrocket
の利用が増えている印象です。
Rocket (Star 21.1k)
#[get("/")] fn index() -> &'static str { "Hello, world!" }
actix-web (Star 18.1k)
- Actix Webは、パワフルで実用的、そして非常に高速なRust用Webフレームワーク
#[get("/hello/{name}")] async fn greet(name: web::Path<String>) -> impl Responder { format!("Hello {name}!") }
axum (Star 11.2k)
- axumは、人間工学とモジュール性に重点を置いたウェブアプリケーションフレームワーク
async fn root() -> &'static str { "Hello, World!" }
リレーショナルデータベース
リレーショナルデータベースを扱う場合、主に「ORMのライブラリを使うケース」と「クエリビルダー/オブジェクマッパーのライブラリを使うケース」の2つがあります。
ORMを使う場合は、ほぼdiesel
が使われており、たまにsea-orm
が使われてるという印象です。また、ORMを使いたくない場合は、sqlx
が使われます。
diesel (Star 10.7k)
- Rustのための安全で拡張可能なORMとクエリビルダ
- PostgreSQL、MySQL、SQLiteをサポートしている
// Entity #[derive(Queryable, Selectable)] #[diesel(table_name = crate::schema::posts)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct Post { pub id: i32, pub title: String, pub body: String, pub published: bool, } // find all models let results = posts .filter(published.eq(true)) .limit(5) .select(Post::as_select()) .load(connection) .expect("Error loading posts");
sea-orm (Star 4.6k)
// Entity #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "cake")] pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub name: String, } // find all models let cakes: Vec<cake::Model> = Cake::find().all(db).await?;
sqlx (Star 9.3k)
// コンパイル時にSQLの内容を検証できる let countries = sqlx::query!( " SELECT country, COUNT(*) as count FROM users GROUP BY country WHERE organization_id = ? ", organization_id ) .fetch_all(&pool) // -> Vec<{ country: String, count: i64 }> .await?; // countries[0].country // countries[0].count
HTMLテンプレートエンジン
WebアプリケーションでHTMLを返す場合はテンプレートエンジンが必要になってきます。askama
が使われることが多い気がする。
シリアライズ・デシリアライズ
Rustではシリアライズ・デシリアライズ時にはserde
が利用されます。また、Web APIでJSONを扱う場合はserde-json
も一緒に利用されます。
serde-rs/serde (Star 7.3k)
use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] struct Point { x: i32, y: i32, } fn main() { let point = Point { x: 1, y: 2 }; // pointをJSON文字列に変換(シリアライズ) let serialized = serde_json::to_string(&point).unwrap(); println!("serialized = {}", serialized); //=> serialized = {"x":1,"y":2} // JSON文字列をpointに変換(デシリアライズ) let deserialized: Point = serde_json::from_str(&serialized).unwrap(); println!("deserialized = {:?}", deserialized); //=> deserialized = Point { x: 1, y: 2 } }
時刻
標準ライブラリのstd::time
では時刻を扱うための基本的な型のみが定義されているので、暦やタイムゾーンなどを扱う場合はchrono
が利用されます。
chrono (Star 2.8k)
let utc: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z` let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
認証
JWTやOauth2を利用して認証をする場合、それぞれライブラリがあるので利用を検討できます。
- jsonwebtoken: RustのJWT(JSON Web Token)のライブラリ
- oauth2-rs: 拡張可能で強く型付けされたRustのOAuth2(RFC6749)のライブラリ
エラーハンドリング
- anyhow (Star 4.2k) :
std::error::Error
をもとに構築された柔軟な具象エラー型。エラーの型がたくさんハンドリングする必要がある場合に、エラーハンドリングを楽にしてくれる