From b8911f194d347485e284f3abd7e803fea4497d53 Mon Sep 17 00:00:00 2001 From: "ray.zh" Date: Sun, 3 Nov 2024 12:49:12 +0800 Subject: [PATCH] =?UTF-8?q?Create=202024-11-03-auxm=20=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E5=A4=9A=E4=B8=AArouter=E5=8F=82=E6=95=B0=E6=97=B6=E6=8A=A5?= =?UTF-8?q?=E9=94=99.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...60\346\227\266\346\212\245\351\224\231.md" | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 "_posts/2024-11-03-auxm \346\263\250\345\206\214\345\244\232\344\270\252router\345\217\202\346\225\260\346\227\266\346\212\245\351\224\231.md" diff --git "a/_posts/2024-11-03-auxm \346\263\250\345\206\214\345\244\232\344\270\252router\345\217\202\346\225\260\346\227\266\346\212\245\351\224\231.md" "b/_posts/2024-11-03-auxm \346\263\250\345\206\214\345\244\232\344\270\252router\345\217\202\346\225\260\346\227\266\346\212\245\351\224\231.md" new file mode 100644 index 0000000..17a58c9 --- /dev/null +++ "b/_posts/2024-11-03-auxm \346\263\250\345\206\214\345\244\232\344\270\252router\345\217\202\346\225\260\346\227\266\346\212\245\351\224\231.md" @@ -0,0 +1,98 @@ +--- +layout: post +title: "auxm 注册多个router参数时报错" +date: 2024-11-03 10:29:20 +0800 +categories: + - rust +tags: + - auxm + - controller注册多个参数报错 +--- + +#### auxm在controller函数定义多个接收参数时报错 + +最近手上有个活,打算用点新东西开发。 刚好最近学习了rust开发。于是心里想:就他了。 + +因为是web项目,网上一搜索,rust web框架auxm还不错。 打开官网就开始搭建demo。 最开始肯定是先写简单的demo函数,`get/post`路径传参,json传参,form表单传参等等。 + +以上都很简单,有手就行。 接着就整合数据库,使用了`sqlx`。 + +根据auxm官网资料, auxm整合sqlx需要先初始化实例,然后注册到路由上下文中,这样就可以动态注入了。 + +官网的代码一般给的示例都是单独的,比如接收path参数示例,router方法就一个接收path参数。接收json方法,也只定义了一个接收json的参数。我去看了下router注册函数,官方解释是可以接收一个或多个extract。 + +那就很简单,把所有需要的申明出来就行了 + +所以大概代码长下面这样(注意addusers函数): + +```rust +pub async fn init(dburi:&String) -> Router { +// 初始化数据库连接 + let dbpool:Pool = MySqlPoolOptions::new() + .max_connections(5) + .acquire_timeout(Duration::from_secs(3)) + .connect(dburi) + .await + .expect("can't connect to database"); + + let route = Router::new() + .route("/", get(|| async { "Hello, World!" })) + .route( + "/addusers/:id", + post(controller::create_user), + ) + // 注入到router中 + .with_state(dbpool) + ; + route +} + + +pub async fn create_user( + Path(id): Path, + Json(payload): Json, + State(pool): State> + + + ) -> Json{ + + + Json(BaseRes { code: 0, msg: payload.name }) +} + +``` + +写完代码,立马我被教育了:vscode马上提示错误,router注册`addusers`函数那里代码报错: +```rust +the trait bound `fn(axum::extract::Path, axum::Json, axum::extract::State>) -> impl Future> {create_user}: Handler<_, _>` is not satisfied +the full name for the type has been written to 'D:\workspace\rust\rust-web-starter\target\debug\deps\rust_web_starter-37beb1a7e3065925.long-type-10239921290377372162.txt' +consider using `--verbose` to print the full type name to the console +Consider using `#[axum::debug_handler]` to improve the error message +the following other types implement trait `Handler`: + `MethodRouter` implements `Handler<(), S>` + `axum::handler::Layered` implements `Handler`rustcClick for full compiler diagnostic +``` +我不过就是整合了下,怎么就报错了嘞? + +不死心又在官网上看了一圈,依然没找到什么。心里也是懵了,这什么情况? + +最后不死心,又找了几个小时,终于官网找到了答案:就是router定义参数,必须严格按照顺序,先解析请求头,再解析上下文请求体,最后解析请求体。所以以上代码定义应该是: + +```rust +pub async fn create_user( + Path(id): Path, + State(pool): State>, + Json(payload): Json, + + + + ) -> Json{ + + + Json(BaseRes { code: 0, msg: payload.name }) +} + +``` +上面代码就不报错了,唉。活见久。 + +[点击查看官方文档-router函数参数顺序](https://docs.rs/axum/latest/axum/extract/index.html#the-order-of-extractors)