微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Actix Web 不处理发布请求?

如何解决Actix Web 不处理发布请求?

所以我正在尝试创建一个基本的 actix-web 应用程序,它将允许我创建一个非常基本的博客系统。它正在处理我的 GET 请求,但不处理我的 POST 请求。

main.rs:

use actix_web::{HttpServer,App,web};
use sqlx::postgres::PgPool;
use dotenv::dotenv;

mod posts;
mod database;

#[actix_web::main]
pub async fn main() -> std::io::Result<()>{
    dotenv().ok();

    let pool = PgPool::connect(&dotenv::var("DATABASE_URL").unwrap()).await.unwrap();

    HttpServer::new(move || {
        // The scope for all post services
        let posts = web::scope("/posts").service(posts::get_all_posts).service(posts::create_post);

        App::new()
            .data(pool.clone())
            .service(web::scope("/api").service(posts))
    })
    .bind(("127.0.0.1",8080))?
    .run()
    .await
}

posts/routes.rs:

use super::*;
use database::{NewPost,model::Post};
use actix_web::{get,post,Responder,HttpResponse};

#[get("/")]
pub async fn get_all_posts(pool: web::Data<PgPool>) -> impl Responder {
    println!("New GET request for all posts!");
    let result = Post::find_all(pool.get_ref()).await;

    match result {
        Ok(posts) => HttpResponse::Ok().json(posts),_ => HttpResponse::BadRequest().body("Error trying to read all the posts from the database") 
    }
}

#[post("/new")]
pub async fn create_post(post: web::Json<NewPost>,pool: web::Data<PgPool>) -> impl Responder {
    println!("New POST request to create a post!");
    let result = Post::new_post(post.into_inner(),pool.as_ref()).await;

    match result {
        Ok(post) => HttpResponse::Ok().json(post),_ => HttpResponse::BadRequest().body("Error trying to create a new post")
    }
}

数据库/model.rs:

use serde::{Serialize,Deserialize};
use sqlx::{Fromrow,PgPool,Row,postgres::PgRow};
use uuid::Uuid;
use chrono::prelude::*;

/// Struct to represent database record.
#[derive(Serialize,Fromrow,Debug)]
pub struct Post {
    pub id: Uuid,pub content: String,pub created_at: chrono::NaiveDateTime
}

/// Struct to receive user input.
#[derive(Serialize,Deserialize)]
pub struct NewPost {
    pub content: String
}

impl Post {
    pub async fn find_all(pool: &PgPool) -> std::io::Result<Vec<Post>> {
        let mut posts = Vec::new();
        let recs = sqlx::query_as!(Post,r#"SELECT id,content,created_at FROM post ORDER BY id"#)
            .fetch_all(pool)
            .await
            .unwrap();

        for rec in recs {
            posts.push(Post {
                id: rec.id,content: rec.content,created_at: rec.created_at
            });
        }

        Ok(posts)
    }

    pub async fn new_post(post: NewPost,pool: &PgPool) -> std::io::Result<Post> {
        let mut tx = pool.begin().await.unwrap();
        let post = sqlx::query("INSERT INTO post (id,created_at) VALUES ($1,$2,$3) RETURNING id,created_at")
            .bind(Uuid::new_v4())
            .bind(post.content)
            .bind(Utc::Now())
            .map(|row: PgRow| {
                Post {
                    id: row.get(0),content: row.get(1),created_at: row.get(2)
                }
            })
            .fetch_one(&mut tx)
            .await
            .unwrap();

        tx.commit().await.unwrap();
        Ok(post)
    }
}

目前,我正在使用 curl 来测试 API。当我想发送 GET 请求时,我使用以下命令:

curl localhost:8080/api/posts/

当我运行这个命令时,我的 Rust 应用程序会打印出以下语句:“所有帖子的新 GET 请求!”正如我所料。

当我想发送 POST 请求时,我使用以下命令:

curl -H "Content-Type: application/json" -X POST -d '{ \
    "content": "This is my first post" \
}' localhost:8080/api/posts/new

运行此 curl 命令后,我根本没有得到任何输出,curl 终端也没有任何输出,我的 Rust 程序也没有任何输出

解决方法

只是阅读所有内容,您的卷发实际上可能是罪魁祸首。

如果您包含 -i 以显示响应标头,那么您可以看到您实际上收到了一个 400 错误请求。

$ curl -i -H "Content-Type: application/json" -X POST -d '{ \
>     "content": "This is my first post" \
> }' localhost:8080/api/posts/new
HTTP/1.1 400 Bad Request
content-length: 0
date: Sun,03 Jan 2021 14:04:12 GMT

如果您将 create_post 更改为采用 post: String 而不是 post: web::Json<NewPost>,则可以更轻松地检查端点正在接收的负载。

pub async fn create_post(post: String) -> impl Responder {
    println!("{}",post);

现在执行相同的 curl 会显示以下输出:

{ \
    "content": "This is my first post" \
}

简而言之,问题是反斜杠保留在有效负载中。因此,要使其正常工作,您唯一需要做的就是删除反斜杠。

curl -H "Content-Type: application/json" -X POST -d '{
    "content": "This is my first post"
}' localhost:8080/api/posts/new

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。