Zerok
Zerok

Reputation: 1513

How to read HttpRequest body

I'm trying to implement a simple Actix API, and the first method I'm testing, is one for creating a "book" object in a SQLite database. I've got the up.sql, schema, model and DAO (just for encapsulating the DB code) all writen, but I'm lacking a very important part: input.

So now I have to deal with the handler, which should read the HttpRequest (which will come as a JSON format), and then save the object in the SQLite instance. The problem is —and this is as funny as annoying-, I have no idea how to read, at least in a proper way, the body of the request.

I've seen a solution in which you take the raw bytes and parse them, but I guess there are much better and more simple solutions for just reading a request's body. But I couldn't find anything useful.

pub async fn create_book_handler(req: HttpRequest) -> HttpResponse {
    let book: Book = req.  <--- what comes here?
    books_dao::create_book(&book);
    let response = Json(book);
    HttpResponse::Ok()
        .content_type(ContentType::json())
        .json(response)
}

Upvotes: 4

Views: 1436

Answers (1)

Tobias S.
Tobias S.

Reputation: 23905

Actix Web uses "extractors" as a type-safe way to extract information from the request. One of those extractors is web::Json which allows deserializing of the body into a given type.

Your struct needs to implement the Deserialize trait provided by serde.

#[derive(serde::Deserialize)]
struct Book {
    title: String,
}

The only thing left to do is to specify the extractor of type web::Json<Book> as the parameter of your route function.

async fn some_route(book: web::Json<Book>) -> Result<String> {
    Ok(format!("This book is called {}!", book.title))
}

Actix Web will automatically call the from_request method of web::Json to deserialize the JSON body into the struct when the route is called.

Upvotes: 4

Related Questions