1
0
mirror of https://github.com/actix/actix-website synced 2024-12-18 01:43:59 +01:00

Update examples/{extractors, errors} to futures 0.3 and actix-web 2.0 (#130)

* Update to futures 0.3

* update examples/errors to actix-web 2.0
This commit is contained in:
Dominic 2019-12-28 16:26:17 +01:00 committed by Yuki Okushi
parent c6c5446937
commit 20517d415d
17 changed files with 120 additions and 102 deletions

View File

@ -4,7 +4,9 @@ version = "1.0.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
actix-web = "1.0" actix-web = "2.0.0"
failure = "0.1" actix-rt = "1.0.0"
env_logger = "0.6" env_logger = "0.7.1"
log = "0.4" log = "0.4.8"
failure = "0.1.6"
actix-http = "1.0.1"

View File

@ -7,19 +7,19 @@ struct MyError {
name: &'static str, name: &'static str,
} }
pub fn index() -> Result<&'static str> { async fn index() -> Result<&'static str> {
let result: Result<&'static str, MyError> = Err(MyError { name: "test error" }); let result: Result<&'static str, MyError> = Err(MyError { name: "test error" });
Ok(result.map_err(|e| error::ErrorBadRequest(e.name))?) Ok(result.map_err(|e| error::ErrorBadRequest(e.name))?)
} }
// </helpers> // </helpers>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::HttpServer; use actix_web::HttpServer;
HttpServer::new(|| App::new().route("/", web::get().to(index))) HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -12,13 +12,14 @@ pub struct MyError {
// Use default implementation for `error_response()` method // Use default implementation for `error_response()` method
impl error::ResponseError for MyError {} impl error::ResponseError for MyError {}
pub fn index() -> Result<&'static str, MyError> { async fn index() -> Result<&'static str, MyError> {
let err = MyError { name: "test error" }; let err = MyError { name: "test error" };
debug!("{}", err); debug!("{}", err);
Err(err) Err(err)
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{middleware::Logger, web, App, HttpServer}; use actix_web::{middleware::Logger, web, App, HttpServer};
std::env::set_var("RUST_LOG", "my_errors=debug,actix_web=info"); std::env::set_var("RUST_LOG", "my_errors=debug,actix_web=info");
@ -30,9 +31,8 @@ pub fn main() {
.wrap(Logger::default()) .wrap(Logger::default())
.route("/", web::get().to(index)) .route("/", web::get().to(index))
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </logging> // </logging>

View File

@ -10,24 +10,24 @@ use failure::Fail;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
#[fail(display = "my error")] #[fail(display = "my error")]
pub struct MyError { struct MyError {
name: &'static str, name: &'static str,
} }
// Use default implementation for `error_response()` method // Use default implementation for `error_response()` method
impl error::ResponseError for MyError {} impl error::ResponseError for MyError {}
fn index() -> Result<&'static str, MyError> { async fn index() -> Result<&'static str, MyError> {
Err(MyError { name: "test" }) Err(MyError { name: "test" })
} }
// </response-error> // </response-error>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{web, App, HttpServer}; use actix_web::{web, App, HttpServer};
HttpServer::new(|| App::new().route("/", web::get().to(index))) HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -1,6 +1,7 @@
use actix_web::{web, App}; use actix_web::{web, App};
// <override> // <override>
use actix_web::{error, http, HttpResponse}; use actix_http::ResponseBuilder;
use actix_web::{error, http::header, http::StatusCode, HttpResponse};
use failure::Fail; use failure::Fail;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
@ -15,30 +16,35 @@ enum MyError {
impl error::ResponseError for MyError { impl error::ResponseError for MyError {
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
match *self { ResponseBuilder::new(self.status_code())
MyError::InternalError => { .set_header(header::CONTENT_TYPE, "text/html; charset=utf-8")
HttpResponse::new(http::StatusCode::INTERNAL_SERVER_ERROR) .body(self.to_string())
} }
MyError::BadClientData => HttpResponse::new(http::StatusCode::BAD_REQUEST),
MyError::Timeout => HttpResponse::new(http::StatusCode::GATEWAY_TIMEOUT), fn status_code(&self) -> StatusCode {
match *self {
MyError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
MyError::BadClientData => StatusCode::BAD_REQUEST,
MyError::Timeout => StatusCode::GATEWAY_TIMEOUT,
} }
} }
} }
fn index() -> Result<&'static str, MyError> { async fn index() -> Result<&'static str, MyError> {
Err(MyError::BadClientData) Err(MyError::BadClientData)
} }
// </override> // </override>
fn error2() -> Result<&'static str, MyError> { async fn error2() -> Result<&'static str, MyError> {
Err(MyError::InternalError) Err(MyError::InternalError)
} }
fn error3() -> Result<&'static str, MyError> { async fn error3() -> Result<&'static str, MyError> {
Err(MyError::Timeout) Err(MyError::Timeout)
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::HttpServer; use actix_web::HttpServer;
HttpServer::new(|| { HttpServer::new(|| {
@ -47,8 +53,7 @@ pub fn main() {
.route("/e2", web::get().to(error2)) .route("/e2", web::get().to(error2))
.route("/e3", web::get().to(error3)) .route("/e3", web::get().to(error3))
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -1,5 +1,6 @@
// <recommend-one> // <recommend-one>
use actix_web::{error, http, HttpResponse}; use actix_http::ResponseBuilder;
use actix_web::{error, http::header, http::StatusCode, HttpResponse};
use failure::Fail; use failure::Fail;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
@ -10,26 +11,29 @@ enum UserError {
impl error::ResponseError for UserError { impl error::ResponseError for UserError {
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
match *self { ResponseBuilder::new(self.status_code())
UserError::ValidationError { .. } => { .set_header(header::CONTENT_TYPE, "text/html; charset=utf-8")
HttpResponse::new(http::StatusCode::BAD_REQUEST) .body(self.to_string())
} }
fn status_code(&self) -> StatusCode {
match *self {
UserError::ValidationError { .. } => StatusCode::BAD_REQUEST,
} }
} }
} }
// </recommend-one> // </recommend-one>
fn index() -> Result<&'static str, UserError> { async fn index() -> Result<&'static str, UserError> {
Err(UserError::ValidationError { Err(UserError::ValidationError {
field: "bad stuff".to_string(), field: "bad stuff".to_string(),
}) })
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{web, App, HttpServer}; use actix_web::{web, App, HttpServer};
HttpServer::new(|| App::new().route("/", web::get().to(index))) HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -1,5 +1,6 @@
// <recommend-two> // <recommend-two>
use actix_web::{error, http, HttpResponse}; use actix_http::ResponseBuilder;
use actix_web::{error, http::header, http::StatusCode, HttpResponse};
use failure::Fail; use failure::Fail;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
@ -10,15 +11,18 @@ enum UserError {
impl error::ResponseError for UserError { impl error::ResponseError for UserError {
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
match *self { ResponseBuilder::new(self.status_code())
UserError::InternalError => { .set_header(header::CONTENT_TYPE, "text/html; charset=utf-8")
HttpResponse::new(http::StatusCode::INTERNAL_SERVER_ERROR) .body(self.to_string())
} }
fn status_code(&self) -> StatusCode {
match *self {
UserError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
} }
} }
} }
fn index() -> Result<&'static str, UserError> { async fn index() -> Result<&'static str, UserError> {
do_thing_that_failes().map_err(|_e| UserError::InternalError)?; do_thing_that_failes().map_err(|_e| UserError::InternalError)?;
Ok("success!") Ok("success!")
} }
@ -28,12 +32,12 @@ fn do_thing_that_failes() -> Result<(), std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::Other, "some error")) Err(std::io::Error::new(std::io::ErrorKind::Other, "some error"))
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{web, App, HttpServer}; use actix_web::{web, App, HttpServer};
HttpServer::new(|| App::new().route("/", web::get().to(index))) HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -4,7 +4,8 @@ version = "1.0.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
actix-web = "1.0" actix-web = "2.0"
actix-rt = "1.0"
serde = "1.0" serde = "1.0"
futures = "0.1" futures = "0.3"
serde_json = "1.0" serde_json = "1.0"

View File

@ -10,17 +10,17 @@ struct FormData {
/// extract form data using serde /// extract form data using serde
/// this handler gets called only if the content type is *x-www-form-urlencoded* /// this handler gets called only if the content type is *x-www-form-urlencoded*
/// and the content of the request could be deserialized to a `FormData` struct /// and the content of the request could be deserialized to a `FormData` struct
fn index(form: web::Form<FormData>) -> Result<String> { async fn index(form: web::Form<FormData>) -> Result<String> {
Ok(format!("Welcome {}!", form.username)) Ok(format!("Welcome {}!", form.username))
} }
// </form> // </form>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| App::new().route("/", web::post().to(index))) HttpServer::new(|| App::new().route("/", web::post().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -8,17 +8,17 @@ struct Info {
} }
/// deserialize `Info` from request's body /// deserialize `Info` from request's body
fn index(info: web::Json<Info>) -> Result<String> { async fn index(info: web::Json<Info>) -> Result<String> {
Ok(format!("Welcome {}!", info.username)) Ok(format!("Welcome {}!", info.username))
} }
// </json-one> // </json-one>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| App::new().route("/", web::post().to(index))) HttpServer::new(|| App::new().route("/", web::post().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -8,11 +8,12 @@ struct Info {
} }
/// deserialize `Info` from request's body, max payload size is 4kb /// deserialize `Info` from request's body, max payload size is 4kb
fn index(info: web::Json<Info>) -> impl Responder { async fn index(info: web::Json<Info>) -> impl Responder {
format!("Welcome {}!", info.username) format!("Welcome {}!", info.username)
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| { HttpServer::new(|| {
@ -34,9 +35,8 @@ pub fn main() {
.route(web::post().to(index)), .route(web::post().to(index)),
) )
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </json-two> // </json-two>

View File

@ -1,5 +1,4 @@
use actix_web::{web, App, FromRequest, HttpRequest, HttpServer, Responder}; use actix_web::{web, App, FromRequest, HttpRequest, HttpServer, Responder};
use futures::future::Future;
use serde::Deserialize; use serde::Deserialize;
// pub mod custom_handler; // pub mod custom_handler;
@ -19,31 +18,34 @@ struct MyInfo {
} }
// <option-one> // <option-one>
fn index(path: web::Path<(String, String)>, json: web::Json<MyInfo>) -> impl Responder { async fn index(
path: web::Path<(String, String)>,
json: web::Json<MyInfo>,
) -> impl Responder {
format!("{} {} {} {}", path.0, path.1, json.id, json.username) format!("{} {} {} {}", path.0, path.1, json.id, json.username)
} }
// </option-one> // </option-one>
// <option-two> // <option-two>
fn extract(req: HttpRequest) -> impl Responder { async fn extract(req: HttpRequest) -> impl Responder {
let params = web::Path::<(String, String)>::extract(&req).unwrap(); let params = web::Path::<(String, String)>::extract(&req).await.unwrap();
let info = web::Json::<MyInfo>::extract(&req) let info = web::Json::<MyInfo>::extract(&req)
.wait() .await
.expect("Err with reading json."); .expect("Err with reading json.");
format!("{} {} {} {}", params.0, params.1, info.username, info.id) format!("{} {} {} {}", params.0, params.1, info.username, info.id)
} }
// </option-two> // </option-two>
fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| { HttpServer::new(|| {
App::new() App::new()
.route("/{name}/{id}", web::post().to(index)) .route("/{name}/{id}", web::post().to(index))
.route("/{name}/{id}/extract", web::post().to(extract)) .route("/{name}/{id}/extract", web::post().to(extract))
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -7,14 +7,15 @@ struct Info {
username: String, username: String,
} }
fn index((path, query): (web::Path<(u32, String)>, web::Query<Info>)) -> String { async fn index((path, query): (web::Path<(u32, String)>, web::Query<Info>)) -> String {
format!( format!(
"Welcome {}, friend {}, userid {}!", "Welcome {}, friend {}, userid {}!",
query.username, path.1, path.0 query.username, path.1, path.0
) )
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| { HttpServer::new(|| {
@ -23,9 +24,8 @@ pub fn main() {
web::get().to(index), web::get().to(index),
) )
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </multi> // </multi>

View File

@ -4,11 +4,12 @@ use actix_web::{web, Result};
/// extract path info from "/users/{userid}/{friend}" url /// extract path info from "/users/{userid}/{friend}" url
/// {userid} - - deserializes to a u32 /// {userid} - - deserializes to a u32
/// {friend} - deserializes to a String /// {friend} - deserializes to a String
fn index(info: web::Path<(u32, String)>) -> Result<String> { async fn index(info: web::Path<(u32, String)>) -> Result<String> {
Ok(format!("Welcome {}, userid {}!", info.1, info.0)) Ok(format!("Welcome {}, userid {}!", info.1, info.0))
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| { HttpServer::new(|| {
@ -17,9 +18,8 @@ pub fn main() {
web::get().to(index), web::get().to(index),
) )
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </path-one> // </path-one>

View File

@ -1,14 +1,15 @@
use actix_web::{web, HttpRequest, Result}; use actix_web::{web, HttpRequest, Result};
// <path-three> // <path-three>
fn index(req: HttpRequest) -> Result<String> { async fn index(req: HttpRequest) -> Result<String> {
let name: String = req.match_info().get("friend").unwrap().parse().unwrap(); let name: String = req.match_info().get("friend").unwrap().parse().unwrap();
let userid: i32 = req.match_info().query("userid").parse().unwrap(); let userid: i32 = req.match_info().query("userid").parse().unwrap();
Ok(format!("Welcome {}, userid {}!", name, userid)) Ok(format!("Welcome {}, userid {}!", name, userid))
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| { HttpServer::new(|| {
@ -17,9 +18,8 @@ pub fn main() {
web::get().to(index), web::get().to(index),
) )
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </path-three> // </path-three>

View File

@ -9,11 +9,12 @@ struct Info {
} }
/// extract path info using serde /// extract path info using serde
fn index(info: web::Path<Info>) -> Result<String> { async fn index(info: web::Path<Info>) -> Result<String> {
Ok(format!("Welcome {}, userid {}!", info.friend, info.userid)) Ok(format!("Welcome {}, userid {}!", info.friend, info.userid))
} }
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| { HttpServer::new(|| {
@ -22,9 +23,8 @@ pub fn main() {
web::get().to(index), web::get().to(index),
) )
}) })
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </path-two> // </path-two>

View File

@ -8,17 +8,17 @@ struct Info {
} }
// this handler get called only if the request's query contains `username` field // this handler get called only if the request's query contains `username` field
fn index(info: web::Query<Info>) -> String { async fn index(info: web::Query<Info>) -> String {
format!("Welcome {}!", info.username) format!("Welcome {}!", info.username)
} }
// </query> // </query>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| App::new().route("/", web::get().to(index))) HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }