1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2025-01-05 14:58:44 +00:00

update json example and guide info

This commit is contained in:
Nikolay Kim 2017-12-25 08:12:13 -08:00
parent b0c8fa03f0
commit a578262f73
3 changed files with 57 additions and 9 deletions

View file

@ -1,12 +1,14 @@
extern crate actix; extern crate actix;
extern crate actix_web; extern crate actix_web;
extern crate bytes;
extern crate futures; extern crate futures;
extern crate env_logger; extern crate env_logger;
extern crate serde_json; extern crate serde_json;
#[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_derive;
use actix_web::*; use actix_web::*;
use futures::Future; use bytes::BytesMut;
use futures::{Future, Stream};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct MyObj { struct MyObj {
@ -14,8 +16,10 @@ struct MyObj {
number: i32, number: i32,
} }
/// This handler uses `HttpRequest::json()` for loading json object.
fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> { fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
req.json().from_err() req.json()
.from_err() // convert all errors into `Error`
.and_then(|val: MyObj| { .and_then(|val: MyObj| {
println!("model: {:?}", val); println!("model: {:?}", val);
Ok(httpcodes::HTTPOk.build().json(val)?) // <- send response Ok(httpcodes::HTTPOk.build().json(val)?) // <- send response
@ -23,6 +27,38 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
.responder() .responder()
} }
const MAX_SIZE: usize = 262_144; // max payload size is 256k
/// This handler manually load request payload and parse json
fn index_manual(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
// readany() returns asynchronous stream of Bytes objects
req.payload_mut().readany()
// `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
.and_then(|body| {
// body is loaded, now we can deserialize json
let obj = serde_json::from_slice::<MyObj>(&body)?;
Ok(httpcodes::HTTPOk.build().json(obj)?) // <- send response
})
.responder()
}
fn main() { fn main() {
::std::env::set_var("RUST_LOG", "actix_web=info"); ::std::env::set_var("RUST_LOG", "actix_web=info");
let _ = env_logger::init(); let _ = env_logger::init();
@ -32,6 +68,7 @@ fn main() {
Application::new() Application::new()
// enable logger // enable logger
.middleware(middlewares::Logger::default()) .middleware(middlewares::Logger::default())
.resource("/manual", |r| r.method(Method::POST).f(index_manual))
.resource("/", |r| r.method(Method::POST).f(index))}) .resource("/", |r| r.method(Method::POST).f(index))})
.bind("127.0.0.1:8080").unwrap() .bind("127.0.0.1:8080").unwrap()
.start(); .start();

View file

@ -13,9 +13,9 @@ a response object. More informatin is available in [handler section](../qs_4.htm
Resource configuraiton is the act of adding a new resource to an application. Resource configuraiton is the act of adding a new resource to an application.
A resource has a name, which acts as an identifier to be used for URL generation. A resource has a name, which acts as an identifier to be used for URL generation.
The name also allows developers to add routes to existing resources. The name also allows developers to add routes to existing resources.
A resource also has a pattern, meant to match against the *PATH* portion of a *URL* A resource also has a pattern, meant to match against the *PATH* portion of a *URL*,
(the portion following the scheme and port, e.g., */foo/bar* in the it does not match against *QUERY* portion (the portion following the scheme and
*URL* *http://localhost:8080/foo/bar*). port, e.g., */foo/bar* in the *URL* *http://localhost:8080/foo/bar?q=value*).
The [Application::resource](../actix_web/struct.Application.html#method.resource) methods The [Application::resource](../actix_web/struct.Application.html#method.resource) methods
add a single resource to application routing table. This method accepts *path pattern* add a single resource to application routing table. This method accepts *path pattern*

View file

@ -69,7 +69,6 @@ deserialized value.
# extern crate actix; # extern crate actix;
# extern crate actix_web; # extern crate actix_web;
# extern crate futures; # extern crate futures;
# extern crate env_logger;
# extern crate serde_json; # extern crate serde_json;
# #[macro_use] extern crate serde_derive; # #[macro_use] extern crate serde_derive;
# use actix_web::*; # use actix_web::*;
@ -95,8 +94,18 @@ Or you can manually load payload into memory and ther deserialize it.
Here is simple example. We will deserialize *MyObj* struct. We need to load request Here is simple example. We will deserialize *MyObj* struct. We need to load request
body first and then deserialize json into object. body first and then deserialize json into object.
```rust,ignore ```rust
fn index(mut req: HttpRequest) -> Future<Item=HttpResponse, Error=Error> { # extern crate actix_web;
# extern crate futures;
# use actix_web::*;
# #[macro_use] extern crate serde_derive;
extern crate serde_json;
use futures::{Future, Stream};
#[derive(Serialize, Deserialize)]
struct MyObj {name: String, number: i32}
fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
// `concat2` will asynchronously read each chunk of the request body and // `concat2` will asynchronously read each chunk of the request body and
// return a single, concatenated, chunk // return a single, concatenated, chunk
req.payload_mut().readany().concat2() req.payload_mut().readany().concat2()
@ -109,10 +118,12 @@ fn index(mut req: HttpRequest) -> Future<Item=HttpResponse, Error=Error> {
let obj = serde_json::from_slice::<MyObj>(&body)?; let obj = serde_json::from_slice::<MyObj>(&body)?;
Ok(httpcodes::HTTPOk.build().json(obj)?) // <- send response Ok(httpcodes::HTTPOk.build().json(obj)?) // <- send response
}) })
.responder()
} }
# fn main() {}
``` ```
Example is available in Complete example for both options is available in
[examples directory](https://github.com/actix/actix-web/tree/master/examples/json/). [examples directory](https://github.com/actix/actix-web/tree/master/examples/json/).