実現したいこと
actix_web::web::Data を使って本番環境ではDBのコネクションを持ったプールをinnerに持ったClient, テスト時はインメモリで定義した構造体を返すClientをAppに渡したいです。UserRepository という trait を定義して、空のstructであるUserClientをimplさせればweb::Dataで包めると思ったのですがうまくいきません。そもそものDataで渡す筋が悪いというのもあるのしょうか?
該当のソースコード
rust
1use actix_web::{ 2 get, 3 web::{self, Data}, 4 App, HttpServer, Responder, 5}; 6use serde::Serialize; 7 8#[derive(Serialize, Debug)] 9pub struct User { 10 pub name: String, 11} 12 13impl User { 14 pub fn new(name: String) -> Self { 15 Self { name } 16 } 17} 18 19pub trait UserRepository { 20 fn get_users(&self) -> Vec<User>; 21} 22 23// インメモリのテスト用クライアント 24#[derive(Debug, Clone)] 25pub struct UserClient; 26 27impl UserRepository for UserClient { 28 fn get_users(&self) -> Vec<User> { 29 vec![User::new("hoge".to_string()), User::new("fuga".to_string())] 30 } 31} 32 33#[get("/users")] 34pub async fn get_users(cl: web::Data<dyn UserRepository>) -> impl Responder { 35 let users = cl.into_inner().get_users(); 36 web::Json(users) 37} 38 39#[actix_rt::main] 40async fn main() -> std::io::Result<()> { 41 std::env::set_var("RUST_LOG", "debug"); 42 std::env::set_var("RUST_BACKTRACE", "1"); 43 env_logger::init(); 44 45 let client: Data<dyn UserRepository> = Data::new(UserClient); 46 47 HttpServer::new(move || { 48 App::new() 49 .app_data(Data::new(client.clone())) 50 .service(get_users) 51 }) 52 .bind("0.0.0.0:9090")? 53 .run() 54 .await 55}
発生している問題・エラーメッセージ
console
1error[E0308]: mismatched types 2 --> examples/user.rs:44:44 3 | 444 | let client: Data<dyn UserRepository> = Data::new(UserClient); 5 | ------------------------ ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn UserRepository`, found struct `UserClient` 6 | | 7 | expected due to this 8 | 9 = note: expected struct `Data<dyn UserRepository>` 10 found struct `Data<UserClient>` 11 12For more information about this error, try `rustc --explain E0308`. 13error: could not compile `actix-web-sample` due to previous error
試したこと
rust
1pub async fn get_users<T: UserRepository>(cl: web::Data<T>) -> impl Responder { 2 let users = cl.into_inner().get_users(); 3 web::Json(users) 4}
といった風にコントローラ側をジェネリクスにしたが、これだとUserClientとして解決できないので違うということは分かります。また、
rust
1 HttpServer::new(move || { 2 App::new() 3 .app_data(Data::new(UserClient)) 4 .service(get_users) 5 })
という風に client を定義せずに直接渡す例も試しました。コンパイル自体は通るのですが、エンドポイントが500を返してうまくいきませんでした。
console
1➜ actix-web git:(master) ✗ http localhost:9090/users 2HTTP/1.1 500 Internal Server Error 3content-length: 96 4content-type: text/plain; charset=utf-8 5date: Fri, 09 Sep 2022 11:13:04 GMT 6 7Requested application data is not configured correctly. View/enable debug logs for more details.
補足情報(FW/ツールのバージョンなど)
toml
1[package] 2name = "actix-web-sample" 3version = "0.1.0" 4edition = "2021" 5 6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 8[dependencies] 9actix-web = "4.0.1" 10actix-rt = "2.7.0" 11serde = { version = "1.0.136", features = ["derive"] } 12env_logger = "0.9.0" 13log = "0.4.17"

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/09/29 11:52