Reputation: 1513
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
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