Trait bound in Actix routes

huangapple go评论63阅读模式
英文:

Trait bound in Actix routes

问题

以下是您提供的文本的翻译部分:

I'm making an API that already works with a few entities. While that part compiles, runs and works okay, I'm having serious problems when adding users: Actix doesn't seem to like the two routes related to them (create_user and user_login). This is my route declaration:

我正在创建一个API,它已经可以与一些实体一起正常工作。尽管这部分可以编译、运行并正常工作,但当添加用户时,我遇到了严重的问题:Actix似乎不喜欢与它们相关的两个路由(create_user和user_login)。这是我的路由声明:

And the error I have is the following:

我遇到的错误如下:

the trait bound fn(actix_web::web::Json<LoginData>, Data<Pool<ConnectionManager<diesel::SqliteConnection>>>) -> HttpResponse {user_login_handler}: Handler<_> is not satisfied
the trait Handler<_> is not implemented for fn(actix_web::web::Json<LoginData>, Data<Pool<ConnectionManager<diesel::SqliteConnection>>>) -> HttpResponse {user_login_handler}

错误是:

特质约束 fn(actix_web::web::Json<LoginData>, Data<Pool<ConnectionManager<diesel::SqliteConnection>>>) -> HttpResponse {user_login_handler}: Handler<_> 未满足
特质 Handler<_> 未实现于 fn(actix_web::web::Json<LoginData>, Data<Pool<ConnectionManager<diesel::SqliteConnection>>>) -> HttpResponse {user_login_handler}

This is the full code of usres_handlers.rs, where you can see the create_user and login_user functions:

这是 usres_handlers.rs 的完整代码,您可以在其中看到 create_userlogin_user 函数:

What am I doing wrong here?

我在这里做错了什么?

英文:

I'm making an API that already works with a few entities. While that part compiles, runs and works okay, I'm having serious problems when adding users: Actix doesn't seem to like the two routes related to them (create_user and user_login). This is my route delcaration:

HttpServer::new(move || {
        App::new()
            .app_data(actix_web::web::Data::new(pool.clone()))
            // User class
            .route(
                "/create_user",
                web::post().to(users_handlers::create_user_handler),
            )
            .route(
                "/login",
                web::post().to(users_handlers::user_login_handler),
            )

And the error I have, is the following:

the trait bound `fn(actix_web::web::Json<LoginData>, Data<Pool<ConnectionManager<diesel::SqliteConnection>>>) -> HttpResponse {user_login_handler}: Handler<_>` is not satisfied
the trait `Handler<_>` is not implemented for `fn(actix_web::web::Json<LoginData>, Data<Pool<ConnectionManager<diesel::SqliteConnection>>>) -> HttpResponse {user_login_handler}`rustcClick for full compiler diagnostic
main.rs(48, 29): required by a bound introduced by this call
route.rs(211, 12): required by a bound in `Route::to`

This is the full code of usres_handlers.rs, where you can see the create_user and login_user functions:

use crate::{
    models::{User, LoginData},
    utils::{log, LogType},
};
use actix_web::{http::header::ContentType, web, HttpResponse};
use diesel::{r2d2::ConnectionManager, SqliteConnection};
mod users_dao;
pub type DbPool = r2d2::Pool<ConnectionManager<SqliteConnection>>;

/**
 * HTTP Handlers for the users API
 * This layer is responsible for handling the HTTP requests and responses,
 * keep log of the errors, and call the DAO layer to interact with the database.
 *
 */

pub fn create_user_handler(user_data: web::Json<User>, pool: web::Data<DbPool>) -> HttpResponse {
    match (validate_user(user_data)) {
        Ok(user) => {
            let result = users_dao::create_user(user_data, pool);
            match result {
                Ok(user) => HttpResponse::Ok()
                    .content_type(ContentType::json())
                    .json(&user),
                Err(err) => {
                    println!("create_user_handler, ERROR: {:#?}", err);
                    log(LogType::Error, err.to_string());
                    HttpResponse::InternalServerError()
                        .content_type(ContentType::json())
                        .body("{err: 'Unable to insert user into database'")
                }
            }
        }
        Err(err) => {
            log(LogType::Error, err.to_string());
            HttpResponse::BadRequest()
                .content_type(ContentType::json())
                .body("{err: 'Unable to validate user data'")
        }
    }
}

pub fn user_login_handler(
    user_data: web::Json<LoginData>,
    pool: web::Data<DbPool>
) -> HttpResponse {
    let result = users_dao::user_login(user_data, pool);

    match (result) {
        Ok(user) => {
            log(LogType::Info, format!("User {} logged in", user.username));
            HttpResponse::Ok()
                    .content_type(ContentType::json())
                    .json(&user)
        },
        Err(err) => {
            log(LogType::Error, err.to_string());
            HttpResponse::BadRequest()
                .content_type(ContentType::json())
                .body("{err: 'Wrong username or password'")
        }
    }
}

// Private functions

fn validate_user(user: web::Json<User>) -> Result<web::Json<User>, &'static str> {
    if user.into_inner().username.is_empty() {
        return Err("Username is required");
    }
    if user.into_inner().password.is_empty() {
        return Err("Password is required");
    }
    Ok(user)
}

What am I doing wrong here?

答案1

得分: 2

尝试将两个函数都标记为asyncHandler要求函数的输出实现Future特性。

英文:

Maybe try and make both functions async? Handler requires the output of a function to implement the Future trait.

huangapple
  • 本文由 发表于 2023年2月23日 19:14:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544059.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定