16
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RustAdvent Calendar 2022

Day 6

Rust で Fast API のように開発する!

Last updated at Posted at 2022-12-05

Python の FastAPI のように、Rust でもWebサーバー側で OpenAPI を生成させたいと考えていました。

axumIssue を覗いてみると、 aide というクレートが有望そうです。
axum 自身は現状ロードマップに取り込むつもりがないようです)

下記が調査で得られた成果物です。Rust の型変更をするだけで、フロントのAPIクライアントがリアルタイムで定義変更を検知します。
(画像の解像度が悪いですが、左が TypeScript, 右が Rust のコードです)

ezgif-1-04c614a4d0.gif

  1. Rust 側のスキーマ変更を cargo watch で監視
  2. aide で OpenAPI を自動生成
  3. OpenAPI から TypeScript の型を自動生成
  4. フロントの axios クライアントが API の定義変更を自動検知

実際に触ってみた感想をまとめました。

ドキュメントは少ない

crate の README.md は非常に少ないです。 examples を参考に調査する必要があります。

スクリーンショット 2022-12-04 10.39.42.png

どのように実装されているのか?

axum のルータを OpenAPI も扱える様に自前実装しています。

次の様な使い方です。

let mut api = aide::openapi::OpenApi::default();


let app = aide::axum::ApiRouter::new()
    .api_route(
        "/todo/:id",
        aide::axum::routing::get(get_todo)
        .delete(delete_todo),
    )
    .api_route(
        "/todo/:id/complete",
        aide::axum::routing::put(complete_todo)
    )
    .nest_api_service(
        "/docs",
        docs_routes()
    )
    .finish_api(&mut api)
    .layer(Extension(Arc::new(api)));

基本的には axum::routing::*aide::axum::routing::* で置き換えれば良い様です。

OpenAPI も出力できる様になる理由を探るため、 axum::routing::get のトレイトを比較してみましょう。

// axum の場合
pub fn get<H, T>(self, handler: H) -> Self
where
    H: Handler<T, S, B>,
    T: 'static,
    S: Send + Sync + 'static,

// aide の場合
pub fn get<H, I, O, T>(self, handler: H) -> Self
where
    H: Handler<T, S, B> + OperationHandler<I, O>,
    I: OperationInput,
    O: OperationOutput,
    B: Send + 'static,
    T: 'static,

aide はトレイトが増えていますね。 OperationHandler というものが増え、このトレイトは axum 本家の Router では知ることのできない OperationInputOperationOutput の情報を追加で持っています。

つまり、 aide の大まかなコンセプトは下記の様になっています。

  • 通常の API サーバとして動作させるとき: Handler<T, S, B> を用いる(axum と同様)
  • OpenAPI を生成したいとき: OperationHandler<I, O> を用いる

なるほど!

aide と FastAPI との比較

両方を利用してみたときの感想です。

aide のメリット

  • エラーレスポンスも型から自動生成できる様になる(例外ではなく Result でエラーを扱うため)

aide のデメリット

  • API のスキーマだけを変更した場合、handler 内のロジックが壊れるので、 todo! を仕込む必要がある
  • トレイトが複雑なのでデバックに時間がかかる
  • ビルドが遅い

Fast API のメリット

  • API のスキーマだけを変更するだけで OpenAPI が出力可能(自動テストは壊れるが、後で直せば良い)
  • ドキュメントが豊富

Fast API のデメリット

  • エラーレスポンスを自動で生成できない
  • OpenAPI の出力結果は間違っている部分がある(Option の扱いとか。 Pydantic V2 に期待)

感想

動かせる様になるまで少し時間がかかりましたが、上手く機能しています。
今後の成長に期待です!

16
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?