ミドルウェア
Towerレイヤー
「ミドルウェア」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
ミドルウェアとは
Middlewareはハンドラーの前後でコードを実行し、リクエストとレスポンスのサイクルをラップします。ロギング、認証、圧縮、タイムアウトなどに使用します。
- Axumは
towerエコシステムを基盤としています - Middlewareはlayersとして追加します
Service trait
TowerはServiceを定義しています。これはリクエストを受け取り、非同期的にレスポンスを生成するものです。LayerはあるServiceを別のServiceでラップします。
Layerの追加
.layer()を使ってMiddlewareを追加します。ここではtower_httpのリクエストトレーシングを追加します。
use axum::{Router, routing::get};
use tower_http::trace::TraceLayer;
fn app() -> Router {
Router::new()
.route("/", get(|| async { "ok" }))
.layer(TraceLayer::new_for_http())
}Layerの順序
Layerは下から上へラップされます。つまり、最後に追加したLayerが最も外側になります。リクエストは外側から内側へ、レスポンスは内側から外側へ流れます。
use axum::{Router, routing::get};
use tower_http::{trace::TraceLayer, compression::CompressionLayer};
fn app() -> Router {
Router::new()
.route("/", get(|| async { "ok" }))
.layer(CompressionLayer::new())
.layer(TraceLayer::new_for_http())
}from_fnによるカスタムMiddleware
middleware::from_fnは非同期関数をMiddlewareに変換します。この関数はリクエストと、チェーンの残りを呼び出すためのNextを受け取ります。
use axum::{middleware::Next, response::Response, extract::Request};
async fn log_mw(req: Request, next: Next) -> Response {
println!("{} {}", req.method(), req.uri());
next.run(req).await
}カスタムMiddlewareの接続
関数をfrom_fnでラップし、Layerとして追加します。
use axum::{Router, routing::get, middleware};
fn app() -> Router {
Router::new()
.route("/", get(|| async { "ok" }))
.layer(middleware::from_fn(log_mw))
}リクエストのショートサーキット
Middlewareはnextを呼び出さずに早期にレスポンスを返せます。これは認証などに便利です。レスポンスを返すとチェーンが停止します。
use axum::{middleware::Next, response::Response, extract::Request, http::StatusCode};
async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
if req.headers().contains_key("authorization") {
Ok(next.run(req).await)
} else {
Err(StatusCode::UNAUTHORIZED)
}
}Middlewareチェーンのモデル化
チェーンは、各関数が次の関数を呼び出すだけのものです。この実行可能な例では、前後をラップする動作をモデル化しています。
fn handler() -> String {
"response".to_string()
}
fn logging<F: Fn() -> String>(next: F) -> String {
println!("-> request in");
let res = next();
println!("<- response out");
res
}
fn main() {
let out = logging(handler);
println!("body: {}", out);
}ルート単位のMiddleware
アプリ全体ではなくメソッドルーターで.layer()を呼び出すと、1つのルートにだけLayerを適用できます。
use axum::{Router, routing::get, middleware};
fn app() -> Router {
Router::new().route(
"/admin",
get(|| async { "admin" }).layer(middleware::from_fn(auth)),
)
}よく使うtower_httpのLayer
tower_httpクレートには、すぐに使えるMiddlewareが用意されています。
- ロギング用の
TraceLayer - gzip用の
CompressionLayer - CORS用の
CorsLayer - リクエスト時間を制限する
TimeoutLayer
use tower_http::cors::CorsLayer;
fn cors() -> CorsLayer {
CorsLayer::permissive()
}ServiceBuilderによる積み重ね
ServiceBuilderを使うと複数のLayerを整理してまとめられます。Layerは上から下へ適用されるため、順序を予測しやすくなります。
use tower::ServiceBuilder;
use tower_http::{trace::TraceLayer, compression::CompressionLayer};
fn stack() -> ServiceBuilder<impl Sized> {
ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new())
}理解度チェック
Middlewareについての理解度を確認しましょう。
まとめ
towerのLayerを使ったMiddlewareについて学びました。
.layer()でMiddlewareを追加します。最後に追加したものが最も外側になりますfrom_fnはNextを使ったカスタムMiddlewareを構築します- 早期にレスポンスを返すとチェーンをショートサーキットできます。認証などに利用できます
tower_httpにはトレーシング、圧縮、CORS、タイムアウト用のLayerがあります
これでAxumコースは完了です。
よくある質問
「ミドルウェア」レッスンは無料ですか?
はい。「ミドルウェア」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「ミドルウェア」で何を学びますか?
Towerレイヤー ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「ミドルウェア」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。