Acteur DB
Définir l'acteur
Dans db.rs
use actix::prelude::*;
pub struct DbExecutor();
impl Actor for DbExecutor {
type Context = SyncContext<Self>;
}
Définir le message GetReviews
use models;
#[derive(Debug)]
pub struct GetReviews {
pub product_id: i32,
}
impl Message for GetReviews {
type Result = Result<Vec<models::Review>, ()>;
}
impl Handler<GetReviews> for DbExecutor {
type Result = Result<Vec<models::Review>, ()>;
fn handle(&mut self, msg: GetReviews, _: &mut Self::Context) -> Self::Result {
warn!("getting reviews for product {}", msg.product_id);
Ok(vec![
models::Review {
product_id: msg.product_id,
review: "great!".to_string(),
reviewer: "user1".to_string(),
},
])
}
}
Définir le message SaveReview
#[derive(Debug)]
pub struct SaveReview {
pub review: models::Review,
}
impl Message for SaveReview {
type Result = Result<models::Review, ()>;
}
impl Handler<SaveReview> for DbExecutor {
type Result = Result<models::Review, ()>;
fn handle(&mut self, msg: SaveReview, _: &mut Self::Context) -> Self::Result {
warn!("saving review {:?}", msg.review);
Ok(msg.review)
}
}
Ajouter l'acteur à l'AppState
Dans lib.rs
use actix::prelude::*;
mod db;
pub struct AppState {
db: Addr<Syn, db::DbExecutor>,
}
let db_addr = SyncArbiter::start(3, move || db::DbExecutor());
server::new(move || {
App::with_state(AppState {
db: db_addr.clone(),
}).middleware(Logger::default())
Appeller l'acteur pendant les requêtes
Dans reviews.rs
use db;
Get des reviews
Enlever
let reviews = vec![];
Et remplacer
futures::future::result({
par:
state
.db
.send(db::GetReviews {
product_id: product_id,
})
.map(|result| match result {
Ok(reviews) => reviews,
Err(err) => {
error!("{:?}", err);
vec![]
}
})
.from_err()
.and_then(move |reviews| {
Save d'une review
Remplacer
futures::future::result({ Ok(HttpResponse::Ok().json(review.clone())) }).responder()
par:
state
.db
.send(db::SaveReview {
review: review_to_save,
})
.from_err()
.and_then(move |_| { Ok(HttpResponse::Ok().json(review.clone())) }).responder()
Résultat
Notre avis s'affiche !
curl localhost:9080/reviews/0 -i
HTTP/1.1 200 OK
content-length: 57
content-type: application/json
date: Thu, 19 Apr 2018 22:13:43 GMT
{"id":0,"reviews":[{"reviewer":"user1","text":"great!"}]}
À la sauvegarde d'un avis, un log s'affiche:
curl localhost:9080/reviews/0 -i -H 'Content-Type: application/json' -d '{"reviewer":"moi","rating":3,"text":"mon avis"}'
HTTP/1.1 200 OK
content-length: 47
content-type: application/json
date: Thu, 19 Apr 2018 22:23:06 GMT
{"reviewer":"moi","text":"mon avis","rating":3}
{"msg":"saving review Review { product_id: 0, reviewer: \"moi\", review: \"mon avis\" }","level":"WARN","ts":"2018-04-20T00:23:06.973686+02:00","logger":"app"}