mirror of
https://github.com/actix/examples
synced 2025-06-28 18:00:37 +02:00
upgrade to 2.0 alpha.3
This commit is contained in:
@ -1,16 +1,17 @@
|
||||
[package]
|
||||
name = "diesel-example"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
workspace = ".."
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "1.0.0"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-web = "2.0.0-alpha.3"
|
||||
|
||||
bytes = "0.4"
|
||||
env_logger = "0.6"
|
||||
futures = "0.1"
|
||||
futures = "0.3.1"
|
||||
uuid = { version = "0.5", features = ["serde", "v4"] }
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
|
@ -14,8 +14,7 @@ use bytes::BytesMut;
|
||||
use diesel::prelude::*;
|
||||
use diesel::r2d2::{self, ConnectionManager};
|
||||
use dotenv;
|
||||
use futures::future::{err, Either};
|
||||
use futures::{Future, Stream};
|
||||
use futures::StreamExt;
|
||||
|
||||
mod models;
|
||||
mod schema;
|
||||
@ -43,15 +42,15 @@ fn query(
|
||||
}
|
||||
|
||||
/// Async request handler
|
||||
fn add(
|
||||
async fn add(
|
||||
name: web::Path<String>,
|
||||
pool: web::Data<Pool>,
|
||||
) -> impl Future<Item = HttpResponse, Error = Error> {
|
||||
) -> Result<HttpResponse, Error> {
|
||||
// run diesel blocking code
|
||||
web::block(move || query(name.into_inner(), pool)).then(|res| match res {
|
||||
Ok(user) => Ok(HttpResponse::Ok().json(user)),
|
||||
Err(_) => Ok(HttpResponse::InternalServerError().into()),
|
||||
})
|
||||
Ok(web::block(move || query(name.into_inner(), pool))
|
||||
.await
|
||||
.map(|user| HttpResponse::Ok().json(user))
|
||||
.map_err(|_| HttpResponse::InternalServerError())?)
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@ -62,62 +61,53 @@ struct MyUser {
|
||||
const MAX_SIZE: usize = 262_144; // max payload size is 256k
|
||||
|
||||
/// This handler manually load request payload and parse json object
|
||||
fn index_add(
|
||||
pl: web::Payload,
|
||||
async fn index_add(
|
||||
mut pl: web::Payload,
|
||||
pool: web::Data<Pool>,
|
||||
) -> impl Future<Item = HttpResponse, Error = Error> {
|
||||
pl
|
||||
// `Future::from_err` acts like `?` in that it coerces the error type from
|
||||
// the future into the final error type
|
||||
.from_err()
|
||||
// `fold` will asynchronously read each chunk of the request body and
|
||||
// call supplied closure, then it resolves to result of closure
|
||||
.fold(BytesMut::new(), move |mut body, chunk| {
|
||||
// limit max size of in-memory payload
|
||||
if (body.len() + chunk.len()) > MAX_SIZE {
|
||||
Err(error::ErrorBadRequest("overflow"))
|
||||
} else {
|
||||
body.extend_from_slice(&chunk);
|
||||
Ok(body)
|
||||
}
|
||||
})
|
||||
// `Future::and_then` can be used to merge an asynchronous workflow with a
|
||||
// synchronous workflow
|
||||
//
|
||||
// Douman NOTE:
|
||||
// The return value in this closure helps, to clarify result for compiler
|
||||
// as otheriwse it cannot understand it
|
||||
.and_then(move |body| {
|
||||
// body is loaded, now we can deserialize serde-json
|
||||
let r_obj = serde_json::from_slice::<MyUser>(&body);
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let mut body = BytesMut::new();
|
||||
// pl.next() gets next item from asynchronous stream of byte chunks
|
||||
// it resolves to `Option<Result<Bytes, Error>>` object
|
||||
// `None` - indicaets end of stream
|
||||
while let Some(chunk) = pl.next().await {
|
||||
let chunk = chunk?;
|
||||
|
||||
// Send to the db for create
|
||||
match r_obj {
|
||||
Ok(obj) => {
|
||||
Either::A(web::block(move || query(obj.name, pool)).then(|res| {
|
||||
match res {
|
||||
Ok(user) => Ok(HttpResponse::Ok().json(user)),
|
||||
Err(_) => Ok(HttpResponse::InternalServerError().into()),
|
||||
}
|
||||
}))
|
||||
}
|
||||
Err(_) => Either::B(err(error::ErrorBadRequest("Json Decode Failed"))),
|
||||
}
|
||||
})
|
||||
// limit max size of in-memory payload
|
||||
if (body.len() + chunk.len()) > MAX_SIZE {
|
||||
return Err(error::ErrorBadRequest("overflow"));
|
||||
}
|
||||
body.extend_from_slice(&chunk);
|
||||
}
|
||||
|
||||
// body is loaded, now we can deserialize serde-json
|
||||
let r_obj = serde_json::from_slice::<MyUser>(&body);
|
||||
|
||||
// Send to the db for create return response to peer
|
||||
match r_obj {
|
||||
Ok(obj) => {
|
||||
let user = web::block(move || query(obj.name, pool))
|
||||
.await
|
||||
.map_err(|_| Error::from(HttpResponse::InternalServerError()))?;
|
||||
Ok(HttpResponse::Ok().json(user))
|
||||
}
|
||||
Err(_) => Err(error::ErrorBadRequest("Json Decode Failed")),
|
||||
}
|
||||
}
|
||||
|
||||
fn add2(
|
||||
async fn add2(
|
||||
item: web::Json<MyUser>,
|
||||
pool: web::Data<Pool>,
|
||||
) -> impl Future<Item = HttpResponse, Error = Error> {
|
||||
) -> Result<HttpResponse, Error> {
|
||||
// run diesel blocking code
|
||||
web::block(move || query(item.into_inner().name, pool)).then(|res| match res {
|
||||
Ok(user) => Ok(HttpResponse::Ok().json(user)),
|
||||
Err(_) => Ok(HttpResponse::InternalServerError().into()),
|
||||
})
|
||||
let user = web::block(move || query(item.into_inner().name, pool))
|
||||
.await
|
||||
.map_err(|_| HttpResponse::InternalServerError())?; // convert diesel error to http response
|
||||
|
||||
Ok(HttpResponse::Ok().json(user))
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
std::env::set_var("RUST_LOG", "actix_web=info");
|
||||
env_logger::init();
|
||||
|
||||
@ -153,14 +143,15 @@ fn main() -> std::io::Result<()> {
|
||||
.into()
|
||||
}),
|
||||
)
|
||||
.route(web::post().to_async(add2)),
|
||||
.route(web::post().to(add2)),
|
||||
)
|
||||
// Manual parsing would allow custom error construction, use of
|
||||
// other parsers *beside* json (for example CBOR, protobuf, xml), and allows
|
||||
// an application to standardise on a single parser implementation.
|
||||
.service(web::resource("/add").route(web::post().to_async(index_add)))
|
||||
.service(web::resource("/add/{name}").route(web::get().to_async(add)))
|
||||
.service(web::resource("/add").route(web::post().to(index_add)))
|
||||
.service(web::resource("/add/{name}").route(web::get().to(add)))
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.run()
|
||||
.start()
|
||||
.await
|
||||
}
|
||||
|
Reference in New Issue
Block a user