1
0
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:
Nikolay Kim
2019-12-07 23:59:24 +06:00
parent e7f7175b7b
commit 3127352797
100 changed files with 1075 additions and 1107 deletions

View File

@ -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"

View File

@ -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
}