1
0
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:
Cameron Dershem
2019-06-17 14:34:23 -04:00
parent f07c78a5ca
commit 507842bf1c
9 changed files with 173 additions and 129 deletions

View File

@ -17,5 +17,6 @@ exclude = [
"async-handlers",
"extractors",
"autoreload",
"errors"
"errors",
"requests",
]

View File

@ -0,0 +1,12 @@
[package]
name = "requests"
version = "0.1.0"
authors = ["Cameron Dershem <cameron@pinkhatbeard.com>"]
edition = "2018"
[dependencies]
serde = "1.0"
serde_json = "1.0"
actix-web = "1.0"
futures = "0.1"
bytes = "0.4"

View 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>

View 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>

View 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>

View 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>

View 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>

View 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() {}