tkzwhr's notes

tkzwhrの技術、中国語などのメモです。

axum0.4の主な変更点

この記事はRust Advent Calendar 2021の記事です。

tokioがメンテナンスしている新しいWebフレームワーク axum のバージョン0.4が2021/12/6にリリースされたので主な変更点をご紹介します。

0.3は破壊的な変更が多かったですが、0.4ではリファクタが中心のようです。

github.com

axum-coreクレートの提供

axumが提供する FromRequest<B>IntoResponse<B> トレイトは拡張性が高く、以前からこれを利用して様々なカスタムリクエストやカスタムレスポンスを実装することができます。

しかし、このトレイトはaxumに実装されているため、これらのトレイトを利用するクレートはこれとは無関係なaxumのバージョンアップに対してもbump upする必要がありました。

axum 0.4ではaxum-coreクレートに分離して提供することで、axum自体のバージョンアップに影響されない作りになります。

これに伴い、axum-coreが axum::body::Body ( hyper::body::Body ) に依存することを避けるために、FromRequest<B>RequestParts<B> で与えられていたデフォルト型パラメータ <B = axum::body::Body> が削除され、明示的な型指定が必要になっています。

MethodRouterのリファクタ

0.3ではRouterに渡す具体的な処理として handlerservice を個別に取り扱う必要があり、MethodRouterもそれぞれのものがありましたが、0.4ではこれらを統一的に扱えるようになりました。

そのため、

  • routing::handler_method_routerrouting::service_method_router にそれぞれに用意されていた getpostaxum::router モジュールの中に定義されている get (handler) や post_service (service) といった関数を利用する
    • これに伴い routing::handler_method_routerrouting::service_method_router は廃止
  • handlerとserviceをまとめてルーティングする
    • Router::new().route("/", get(handler).post_service(service))
  • merge, layer, route_layer, fallback を統一的に扱う
  • 複数routeのサポート
    • Router::new().route("/", get(handler)).route("/", post_service(service))

といったことが可能になっています。

なお、この対応のモチベーションは Overlapping routes with differing methods cause a panic in 0.3.0 · Issue #451 · tokio-rs/axum · GitHub の解決にあるとのことです。

Handler<B, T> のリファクタ

リクエストの型は基本的に axum::body::Body であるため、 Handler で、常に型パラメータ B に対しこの axum::body::Body を与えるのが少し冗長です。

そのため、0.4ではデフォルトの型が与えられるようになりました。そのため、型パラメータの順序が入れ替えられています。

- pub trait Handler<B, T>: Clone + Send + Sized + 'static {
+ pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {