質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

axum

axumとは、Rust製のWebアプリケーション向けのフレームワーク。非同期リクエスト処理に特化しており、非常に高速です。高い保守性を持ち、エラーハンドリングを容易に行うことができます。

Q&A

解決済

1回答

242閲覧

[Rust] axumのルーティングに関するエラーが出ている

donut4

総合スコア170

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

axum

axumとは、Rust製のWebアプリケーション向けのフレームワーク。非同期リクエスト処理に特化しており、非常に高速です。高い保守性を持ち、エラーハンドリングを容易に行うことができます。

0グッド

0クリップ

投稿2024/09/30 15:02

編集2024/10/01 03:37

実現したいこと

Rustで自作アプリを作っています。
サーバーサイド言語とフロントを別々にして作っていて、フロント側でfetchを利用してPOST通信をしていますが、その際にバックエンド側でルーティングに関するエラーが出ていて、解決方法がわからない状態です。

やりたいこととしては、簡単なログイン処理を作っていて、バックエンド側でIDとPWの組み合わせが正しいとき、誤っている時のそれぞれの時に、Result型を使用してフロント側に返したいのですが、上記エラーが障壁となっていてうまく実現できません。

解消方法をご存じの方いたらよろしくお願いしまします。

発生している問題・分からないこと

先述した通り、routing.rs内で「the trait Handler<_, _, _> is not implemented・・・。(ハンドラー関数が実装されていない?)」とエラーが出ていています。

該当のソースコード

check_password.rs

1 2//フロントからのリクエスト保管する構造体 3pub struct RequestForm { 4 login_id: String, 5 password: String, 6} 7 8 impl RequestForm { 9 //フォームリクエスト初期化(省略) 10 11 } 12 13//フロントに返すメッセージを格納する構造体。 14 pub struct LoginResponse { 15 message: String, 16} 17 18pub async fn check_password(Json(payload): Json<RequestForm>)-> Result<Json<LoginResponse>, Json<LoginResponse>> { 19 20 //リクエスト情報を利用できる状態にする(一部省略) 21 let request_data:&RequestForm=&req.get_request_form(); 22 23 //login_idをキーにしてログインに必要なハッシュなどをDBから取得してくる 24 let mut auth_info:Option<auth::Model> = get_auth_info(&db, &request_data).await; 25 26 let mut salt:String = "".to_string(); 27 let mut hash:String = "".to_string(); 28 29 //SELECTの結果がなければErrとしてメッセージと一緒に返却する。 30 match auth_info { 31 Some(record) => { 32 salt = record.salt.unwrap(); 33 hash = record.hash.unwrap(); 34 }, 35 None => { 36 return Err(Json(LoginResponse { 37 message: "ユーザーが見つかりません".to_string(), 38 })); 39 } 40 } 41 42 //IDとPWのくみあわせがあっていれば、ログイン成功、失敗時はそれぞれ、result型で返しメッセージと一緒に返す。 43 if salt + &generate_hash_password(&request_data.password) == hash{ 44 Ok(Json(LoginResponse { 45 message: "ログイン成功".to_string(), 46 })) 47 } else { 48 Err(Json(LoginResponse { 49 message: "ログイン失敗: パスワードが正しくありません".to_string(), 50 })) 51 } 52 53}

routing.rs

1pub async fn running_router() { 2 let app = axum::Router::new() 3 4 //「login::check_password」の箇所でエラーが出ている。 5 .route("/login", routing::post(login::check_password)); 6 7 dotenv().ok(); 8 axum::Server::bind(&env::var("HOST_NAME").unwrap().parse().unwrap()) 9 .serve(app.into_make_service()) 10 .await 11 .unwrap(); 12}

error

1error[E0277]: the trait bound `fn(axum::Json<login::RequestForm>) -> impl Future<Output = Result<axum::Json<LoginResponse>, axum::Json<LoginResponse>>> {check_password}: Handler<_, _, _>` is not satisfied 2 --> src/router/routing.rs:19:34 3 | 419 | .route("/aaa", routing::post(login::check_password)) 5 | ------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(axum::Json<login::RequestForm>) -> impl Future<Output = Result<axum::Json<LoginResponse>, axum::Json<LoginResponse>>> {check_password}` 6 | | 7 | required by a bound introduced by this call 8 | 9 = help: the following other types implement trait `Handler<T, S, B>`: 10 <Layered<L, H, T, S, B, B2> as Handler<T, S, B2>> 11 <MethodRouter<S, B> as Handler<(), S, B>> 12note: required by a bound in `post` 13 --> /home/yonetani/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.6.20/src/routing/method_routing.rs:407:1 14 | 15407 | top_level_handler_fn!(post, POST); 16 | ^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^ 17 | | | 18 | | required by a bound in this function 19 | required by this bound in `post` 20 = note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info) 21 22

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

check_passwordの返り値をResult<String, io::Error>にしたらエラーは出ませんでしたが、フロント側でうまくメッセージ等が受け取れませんでした。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Json で包まれた型が serde::{Deserialize, Serialize} を実装していないようです.

Rust には JSON や YAML,TOML など様々なフォーマットを統一的に扱えるために serde という crate があります.
Axum もこの serde を利用してデータの送受信を行うことができます.

具体的な手順は,

① serde を Cargo.toml に追加する.このとき derive feature が必要.

Cargo.toml

1serde = { version = "1.0", features = ["derive"] }

Extractor example を参考にして,RequestFormserde::Deserialize を derive する.

Response example を参考にして,LoginResponseserde::Serialize を derive する.

これで動くようになるのではないでしょうか.

投稿2024/10/01 04:38

Zomathi

総合スコア35

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

donut4

2024/10/01 11:43

ありがとうございます。 serde::{Deserialize, Serialize}が実装されていなかったです。 エラーも解消され、リクエストが到達できました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問