mirror of
https://github.com/actix/examples
synced 2024-11-23 22:41:07 +01:00
Update basics/todo to v4. (#486)
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
d36c2f0f1f
commit
c01f0ea5f3
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -586,23 +586,6 @@ dependencies = [
|
|||||||
"webpki-roots 0.22.2",
|
"webpki-roots 0.22.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "actix-todo"
|
|
||||||
version = "1.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"actix-files 0.3.0",
|
|
||||||
"actix-session 0.4.1",
|
|
||||||
"actix-web 3.3.3",
|
|
||||||
"diesel",
|
|
||||||
"dotenv",
|
|
||||||
"env_logger 0.8.4",
|
|
||||||
"futures",
|
|
||||||
"log",
|
|
||||||
"serde 1.0.136",
|
|
||||||
"serde_json",
|
|
||||||
"tera",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-utils"
|
name = "actix-utils"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@ -6069,6 +6052,23 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "todo"
|
||||||
|
version = "1.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"actix-files 0.6.0-beta.16",
|
||||||
|
"actix-session 0.5.0-beta.7",
|
||||||
|
"actix-web 4.0.0-rc.1",
|
||||||
|
"diesel",
|
||||||
|
"dotenv",
|
||||||
|
"env_logger 0.9.0",
|
||||||
|
"futures",
|
||||||
|
"log",
|
||||||
|
"serde 1.0.136",
|
||||||
|
"serde_json",
|
||||||
|
"tera",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "0.2.25"
|
version = "0.2.25"
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-todo"
|
name = "todo"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "3"
|
actix-web = "4.0.0-rc.1"
|
||||||
actix-files = "0.3"
|
actix-files = "0.6.0-beta.15"
|
||||||
actix-session = "0.4"
|
actix-session = "0.5.0-beta.7"
|
||||||
|
|
||||||
|
diesel = { version = "1.3.2", features = ["postgres", "r2d2"] }
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
env_logger = "0.8"
|
env_logger = "0.9"
|
||||||
futures = "0.3.1"
|
futures = "0.3.7"
|
||||||
log = "0.4.3"
|
log = "0.4"
|
||||||
serde = { version = "1.0.69", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1.0.22"
|
serde_json = "1"
|
||||||
tera = "1.5.0"
|
tera = "1.5"
|
||||||
|
|
||||||
[dependencies.diesel]
|
|
||||||
features = ["postgres", "r2d2"]
|
|
||||||
version = "1.3.2"
|
|
||||||
|
@ -45,4 +45,4 @@ To run the application execute:
|
|||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
Then to view it in your browser navigate to: [http://localhost:8088/](http://localhost:8088/)
|
Then to view it in your browser navigate to: [http://localhost:8080/](http://localhost:8080/)
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
use actix_files::NamedFile;
|
use actix_files::NamedFile;
|
||||||
use actix_session::Session;
|
use actix_session::Session;
|
||||||
use actix_web::middleware::errhandlers::ErrorHandlerResponse;
|
use actix_web::{
|
||||||
use actix_web::{dev, error, http, web, Error, HttpResponse, Result};
|
dev, error, http, middleware::ErrorHandlerResponse, web, Error, HttpResponse, Result,
|
||||||
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tera::{Context, Tera};
|
use tera::{Context, Tera};
|
||||||
|
|
||||||
use crate::db;
|
use crate::{
|
||||||
use crate::session::{self, FlashMessage};
|
db,
|
||||||
|
session::{self, FlashMessage},
|
||||||
|
};
|
||||||
|
|
||||||
pub async fn index(
|
pub async fn index(
|
||||||
pool: web::Data<db::PgPool>,
|
pool: web::Data<db::PgPool>,
|
||||||
@ -50,7 +53,8 @@ pub async fn create(
|
|||||||
Ok(redirect_to("/"))
|
Ok(redirect_to("/"))
|
||||||
} else {
|
} else {
|
||||||
web::block(move || db::create_task(params.into_inner().description, &pool))
|
web::block(move || db::create_task(params.into_inner().description, &pool))
|
||||||
.await?;
|
.await?
|
||||||
|
.map_err(error::ErrorInternalServerError)?;
|
||||||
session::set_flash(&session, FlashMessage::success("Task successfully added"))?;
|
session::set_flash(&session, FlashMessage::success("Task successfully added"))?;
|
||||||
Ok(redirect_to("/"))
|
Ok(redirect_to("/"))
|
||||||
}
|
}
|
||||||
@ -86,7 +90,9 @@ async fn toggle(
|
|||||||
pool: web::Data<db::PgPool>,
|
pool: web::Data<db::PgPool>,
|
||||||
params: web::Path<UpdateParams>,
|
params: web::Path<UpdateParams>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
web::block(move || db::toggle_task(params.id, &pool)).await?;
|
web::block(move || db::toggle_task(params.id, &pool))
|
||||||
|
.await?
|
||||||
|
.map_err(error::ErrorInternalServerError)?;
|
||||||
Ok(redirect_to("/"))
|
Ok(redirect_to("/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,33 +101,33 @@ async fn delete(
|
|||||||
params: web::Path<UpdateParams>,
|
params: web::Path<UpdateParams>,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
web::block(move || db::delete_task(params.id, &pool)).await?;
|
web::block(move || db::delete_task(params.id, &pool))
|
||||||
|
.await?
|
||||||
|
.map_err(error::ErrorInternalServerError)?;
|
||||||
session::set_flash(&session, FlashMessage::success("Task was deleted."))?;
|
session::set_flash(&session, FlashMessage::success("Task was deleted."))?;
|
||||||
Ok(redirect_to("/"))
|
Ok(redirect_to("/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn redirect_to(location: &str) -> HttpResponse {
|
fn redirect_to(location: &str) -> HttpResponse {
|
||||||
HttpResponse::Found()
|
HttpResponse::Found()
|
||||||
.header(http::header::LOCATION, location)
|
.append_header((http::header::LOCATION, location))
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bad_request<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
pub fn bad_request<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
let new_resp = NamedFile::open("static/errors/400.html")?
|
let new_resp = NamedFile::open("static/errors/400.html")?
|
||||||
.set_status_code(res.status())
|
.set_status_code(res.status())
|
||||||
.into_response(res.request())?;
|
.into_response(res.request())
|
||||||
Ok(ErrorHandlerResponse::Response(
|
.map_into_right_body();
|
||||||
res.into_response(new_resp.into_body()),
|
Ok(ErrorHandlerResponse::Response(res.into_response(new_resp)))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_found<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
pub fn not_found<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
let new_resp = NamedFile::open("static/errors/404.html")?
|
let new_resp = NamedFile::open("static/errors/404.html")?
|
||||||
.set_status_code(res.status())
|
.set_status_code(res.status())
|
||||||
.into_response(res.request())?;
|
.into_response(res.request())
|
||||||
Ok(ErrorHandlerResponse::Response(
|
.map_into_right_body();
|
||||||
res.into_response(new_resp.into_body()),
|
Ok(ErrorHandlerResponse::Response(res.into_response(new_resp)))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn internal_server_error<B>(
|
pub fn internal_server_error<B>(
|
||||||
@ -129,8 +135,7 @@ pub fn internal_server_error<B>(
|
|||||||
) -> Result<ErrorHandlerResponse<B>> {
|
) -> Result<ErrorHandlerResponse<B>> {
|
||||||
let new_resp = NamedFile::open("static/errors/500.html")?
|
let new_resp = NamedFile::open("static/errors/500.html")?
|
||||||
.set_status_code(res.status())
|
.set_status_code(res.status())
|
||||||
.into_response(res.request())?;
|
.into_response(res.request())
|
||||||
Ok(ErrorHandlerResponse::Response(
|
.map_into_right_body();
|
||||||
res.into_response(new_resp.into_body()),
|
Ok(ErrorHandlerResponse::Response(res.into_response(new_resp)))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref as _;
|
||||||
|
|
||||||
use diesel::pg::PgConnection;
|
use diesel::{
|
||||||
use diesel::r2d2::{ConnectionManager, Pool, PoolError, PooledConnection};
|
pg::PgConnection,
|
||||||
|
r2d2::{ConnectionManager, Pool, PoolError, PooledConnection},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::model::{NewTask, Task};
|
use crate::model::{NewTask, Task};
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
#[macro_use]
|
|
||||||
extern crate log;
|
|
||||||
|
|
||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
|
|
||||||
use actix_files as fs;
|
use actix_files::Files;
|
||||||
use actix_session::CookieSession;
|
use actix_session::CookieSession;
|
||||||
use actix_web::middleware::{errhandlers::ErrorHandlers, Logger};
|
use actix_web::{
|
||||||
use actix_web::{http, web, App, HttpServer};
|
http,
|
||||||
|
middleware::{ErrorHandlers, Logger},
|
||||||
|
web, App, HttpServer,
|
||||||
|
};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use tera::Tera;
|
use tera::Tera;
|
||||||
|
|
||||||
@ -24,22 +25,18 @@ static SESSION_SIGNING_KEY: &[u8] = &[0; 32];
|
|||||||
async fn main() -> io::Result<()> {
|
async fn main() -> io::Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
env::set_var("RUST_LOG", "actix_todo=debug,actix_web=info");
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||||
let pool = db::init_pool(&database_url).expect("Failed to create pool");
|
let pool = db::init_pool(&database_url).expect("Failed to create pool");
|
||||||
|
|
||||||
let app = move || {
|
log::info!("starting HTTP serer at http://localhost:8080");
|
||||||
debug!("Constructing the App");
|
|
||||||
|
|
||||||
let mut templates = match Tera::new("templates/**/*") {
|
HttpServer::new(move || {
|
||||||
Ok(t) => t,
|
log::debug!("Constructing the App");
|
||||||
Err(e) => {
|
|
||||||
println!("Parsing error(s): {}", e);
|
let mut templates =
|
||||||
::std::process::exit(1);
|
Tera::new("templates/**/*").expect("errors in tera templates");
|
||||||
}
|
|
||||||
};
|
|
||||||
templates.autoescape_on(vec!["tera"]);
|
templates.autoescape_on(vec!["tera"]);
|
||||||
|
|
||||||
let session_store = CookieSession::signed(SESSION_SIGNING_KEY).secure(false);
|
let session_store = CookieSession::signed(SESSION_SIGNING_KEY).secure(false);
|
||||||
@ -53,17 +50,17 @@ async fn main() -> io::Result<()> {
|
|||||||
.handler(http::StatusCode::NOT_FOUND, api::not_found);
|
.handler(http::StatusCode::NOT_FOUND, api::not_found);
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.data(templates)
|
.app_data(templates)
|
||||||
.data(pool.clone())
|
.app_data(pool.clone())
|
||||||
.wrap(Logger::default())
|
.wrap(Logger::default())
|
||||||
.wrap(session_store)
|
.wrap(session_store)
|
||||||
.wrap(error_handlers)
|
.wrap(error_handlers)
|
||||||
.service(web::resource("/").route(web::get().to(api::index)))
|
.service(web::resource("/").route(web::get().to(api::index)))
|
||||||
.service(web::resource("/todo").route(web::post().to(api::create)))
|
.service(web::resource("/todo").route(web::post().to(api::create)))
|
||||||
.service(web::resource("/todo/{id}").route(web::post().to(api::update)))
|
.service(web::resource("/todo/{id}").route(web::post().to(api::update)))
|
||||||
.service(fs::Files::new("/static", "static/"))
|
.service(Files::new("/static", "./static/"))
|
||||||
};
|
})
|
||||||
|
.bind(("127.0.0.1", 8088))?
|
||||||
debug!("Starting server");
|
.run()
|
||||||
HttpServer::new(app).bind("localhost:8088")?.run().await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
const FLASH_KEY: &str = "flash";
|
const FLASH_KEY: &str = "flash";
|
||||||
|
|
||||||
pub fn set_flash(session: &Session, flash: FlashMessage) -> Result<()> {
|
pub fn set_flash(session: &Session, flash: FlashMessage) -> Result<()> {
|
||||||
session.set(FLASH_KEY, flash)
|
session.insert(FLASH_KEY, flash)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_flash(session: &Session) -> Result<Option<FlashMessage>> {
|
pub fn get_flash(session: &Session) -> Result<Option<FlashMessage>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user