mirror of
https://github.com/actix/actix-website
synced 2025-06-27 15:39:02 +02:00
First pass at Requests Chapter.
This commit is contained in:
21
examples/requests/src/json_two.rs
Normal file
21
examples/requests/src/json_two.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// // <json-two>
|
||||
// use actix_web::{error::Error, HttpRequest, HttpResponse};
|
||||
// use futures::Future;
|
||||
// use serde::{Deserialize, Serialize};
|
||||
|
||||
// #[derive(Debug, Serialize, Deserialize)]
|
||||
// struct MyObj {
|
||||
// name: String,
|
||||
// number: i32,
|
||||
// }
|
||||
|
||||
// fn index(req: HttpRequest) -> Box<Future<Item = HttpResponse, Error = Error>> {
|
||||
// req.json()
|
||||
// .from_err()
|
||||
// .and_then(|val: MyObj| {
|
||||
// println!("model: {:?}", val);
|
||||
// Ok(HttpResponse::Ok().json(val)) // <- send response
|
||||
// })
|
||||
// .responder()
|
||||
// }
|
||||
// // </json-two>
|
23
examples/requests/src/main.rs
Normal file
23
examples/requests/src/main.rs
Normal file
@ -0,0 +1,23 @@
|
||||
mod json_two;
|
||||
mod manual;
|
||||
mod multipart;
|
||||
mod streaming;
|
||||
mod urlencoded;
|
||||
// <json-request>
|
||||
use actix_web::{web, App, Result};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Info {
|
||||
username: String,
|
||||
}
|
||||
|
||||
/// extract `Info` using serde
|
||||
fn index(info: web::Json<Info>) -> Result<String> {
|
||||
Ok(format!("Welcome {}!", info.username))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new().route("/index.html", web::post().to(index));
|
||||
}
|
||||
// </json-request>
|
43
examples/requests/src/manual.rs
Normal file
43
examples/requests/src/manual.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// <json-manual>
|
||||
use actix_web::{error, web, Error, HttpResponse};
|
||||
use bytes::BytesMut;
|
||||
use futures::{Future, Stream};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct MyObj {
|
||||
name: String,
|
||||
number: i32,
|
||||
}
|
||||
|
||||
const MAX_SIZE: usize = 262_144; // max payload size is 256k
|
||||
|
||||
fn index_manual(
|
||||
payload: web::Payload,
|
||||
) -> impl Future<Item = HttpResponse, Error = Error> {
|
||||
// payload is a stream of Bytes objects
|
||||
payload
|
||||
// `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 serde-json
|
||||
let obj = serde_json::from_slice::<MyObj>(&body)?;
|
||||
Ok(HttpResponse::Ok().json(obj)) // <- send response
|
||||
})
|
||||
}
|
||||
// </json-manual>
|
25
examples/requests/src/multipart.rs
Normal file
25
examples/requests/src/multipart.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// <multipart>
|
||||
// use actix_web::{error, Error, HttpRequest, HttpResponse};
|
||||
// use futures::Future;
|
||||
|
||||
// fn index(req: HttpRequest) -> Box<Future<Item = HttpResponse, Error = Error>> {
|
||||
// // get multipart and iterate over multipart items
|
||||
// req.multipart().and_then(|item| match item {
|
||||
// multipart::MultipartItem::Field(field) => {
|
||||
// println!(
|
||||
// "==== FIELD ==== {:?} {:?}",
|
||||
// field.headers(),
|
||||
// field.content_type()
|
||||
// );
|
||||
// Either::A(
|
||||
// field
|
||||
// .map(|chunk| {
|
||||
// println!("-- CHUNK: \n{}", std::str::from_utf8(&chunk).unwrap());
|
||||
// })
|
||||
// .fold((), |_, _| result(Ok(()))),
|
||||
// )
|
||||
// }
|
||||
// multipart::MultipartItem::Nested(mp) => Either::B(result(Ok(()))),
|
||||
// })
|
||||
// }
|
||||
// </multipart>
|
15
examples/requests/src/streaming.rs
Normal file
15
examples/requests/src/streaming.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// <streaming>
|
||||
// use actix_web::{error, web, Error, HttpResponse};
|
||||
// use futures::{future::result, Future, Stream};
|
||||
|
||||
// fn index(payload: web::Payload) -> Box<Future<Item = HttpResponse, Error = Error>> {
|
||||
// payload
|
||||
// .from_err()
|
||||
// .fold((), |_, chunk| {
|
||||
// println!("Chunk: {:?}", chunk);
|
||||
// result::<_, error::PayloadError>(Ok(()))
|
||||
// })
|
||||
// .map(|_| HttpResponse::Ok().finish())
|
||||
// .responder()
|
||||
// }
|
||||
// </streaming>
|
22
examples/requests/src/urlencoded.rs
Normal file
22
examples/requests/src/urlencoded.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// <urlencoded>
|
||||
// use actix_web::{Error, HttpRequest, HttpResponse};
|
||||
// use futures::future::{ok, Future};
|
||||
// use serde::Deserialize;
|
||||
|
||||
// #[derive(Deserialize)]
|
||||
// struct FormData {
|
||||
// username: String,
|
||||
// }
|
||||
|
||||
// fn index(req: &HttpRequest) -> Box<Future<Item = HttpResponse, Error = Error>> {
|
||||
// req.urlencoded::<FormData>() // <- get UrlEncoded future
|
||||
// .from_err()
|
||||
// .and_then(|data| {
|
||||
// // <- deserialized instance
|
||||
// println!("USERNAME: {:?}", data.username);
|
||||
// ok(HttpResponse::Ok().into())
|
||||
// })
|
||||
// .responder()
|
||||
// }
|
||||
// </urlencoded>
|
||||
fn main() {}
|
Reference in New Issue
Block a user