chore: Upgrade to Actix Web 4 (#638)
* chore: Upgrade to actix-web 4 * fix: Update example names for CI tests
This commit is contained in:
parent
d547e107bc
commit
6a22207944
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
@ -293,7 +293,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
path: [basic, actix_example, actix4_example, axum_example, axum-graphql_example, rocket_example, poem_example, jsonrpsee_example]
|
path: [basic, actix_example, actix3_example, axum_example, axum-graphql_example, rocket_example, poem_example, jsonrpsee_example]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
3
examples/actix3_example/.env
Normal file
3
examples/actix3_example/.env
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
HOST=127.0.0.1
|
||||||
|
PORT=8000
|
||||||
|
DATABASE_URL="mysql://root:root@localhost/actix_example"
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sea-orm-actix-4-beta-example"
|
name = "sea-orm-actix-example"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Sam Samai <sam@studio2pi.com.au>"]
|
authors = ["Sam Samai <sam@studio2pi.com.au>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@ -9,12 +9,12 @@ publish = false
|
|||||||
members = [".", "entity", "migration"]
|
members = [".", "entity", "migration"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-files = "0.6.0-beta.4"
|
actix-http = "2"
|
||||||
actix-http = "=3.0.0-beta.5"
|
actix-web = "3"
|
||||||
actix-rt = "2.2.0"
|
actix-flash = "0.2"
|
||||||
actix-service = "=2.0.0-beta.5"
|
actix-files = "0.5"
|
||||||
actix-web = "=4.0.0-beta.5"
|
futures = { version = "^0.3" }
|
||||||
|
futures-util = { version = "^0.3" }
|
||||||
tera = "1.8.0"
|
tera = "1.8.0"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
listenfd = "0.3.3"
|
listenfd = "0.3.3"
|
@ -1,6 +1,8 @@
|
|||||||

|

|
||||||
|
|
||||||
# Actix 4 Beta with SeaORM example app
|
# Actix 3 with SeaORM example app
|
||||||
|
|
||||||
|
> Actix Web 3 has been superseeded by [Actix Web 4](https://github.com/actix/actix-web).
|
||||||
|
|
||||||
1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database
|
1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database
|
||||||
|
|
Before Width: | Height: | Size: 604 KiB After Width: | Height: | Size: 604 KiB |
@ -17,7 +17,7 @@ version = "^0.7.0"
|
|||||||
features = [
|
features = [
|
||||||
"macros",
|
"macros",
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-actix-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
"sqlx-mysql",
|
"sqlx-mysql",
|
||||||
# "sqlx-postgres",
|
# "sqlx-postgres",
|
||||||
# "sqlx-sqlite",
|
# "sqlx-sqlite",
|
@ -1,4 +1,4 @@
|
|||||||
use actix_files::Files as Fs;
|
use actix_files as fs;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
error, get, middleware, post, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result,
|
error, get, middleware, post, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result,
|
||||||
};
|
};
|
||||||
@ -34,7 +34,11 @@ struct FlashData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn list(req: HttpRequest, data: web::Data<AppState>) -> Result<HttpResponse, Error> {
|
async fn list(
|
||||||
|
req: HttpRequest,
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
opt_flash: Option<actix_flash::Message<FlashData>>,
|
||||||
|
) -> Result<HttpResponse, Error> {
|
||||||
let template = &data.templates;
|
let template = &data.templates;
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
|
|
||||||
@ -58,6 +62,11 @@ async fn list(req: HttpRequest, data: web::Data<AppState>) -> Result<HttpRespons
|
|||||||
ctx.insert("posts_per_page", &posts_per_page);
|
ctx.insert("posts_per_page", &posts_per_page);
|
||||||
ctx.insert("num_pages", &num_pages);
|
ctx.insert("num_pages", &num_pages);
|
||||||
|
|
||||||
|
if let Some(flash) = opt_flash {
|
||||||
|
let flash_inner = flash.into_inner();
|
||||||
|
ctx.insert("flash", &flash_inner);
|
||||||
|
}
|
||||||
|
|
||||||
let body = template
|
let body = template
|
||||||
.render("index.html.tera", &ctx)
|
.render("index.html.tera", &ctx)
|
||||||
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
|
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
|
||||||
@ -78,7 +87,7 @@ async fn new(data: web::Data<AppState>) -> Result<HttpResponse, Error> {
|
|||||||
async fn create(
|
async fn create(
|
||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
post_form: web::Form<post::Model>,
|
post_form: web::Form<post::Model>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> actix_flash::Response<HttpResponse, FlashData> {
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
|
|
||||||
let form = post_form.into_inner();
|
let form = post_form.into_inner();
|
||||||
@ -92,9 +101,12 @@ async fn create(
|
|||||||
.await
|
.await
|
||||||
.expect("could not insert post");
|
.expect("could not insert post");
|
||||||
|
|
||||||
Ok(HttpResponse::Found()
|
let flash = FlashData {
|
||||||
.append_header(("location", "/"))
|
kind: "success".to_owned(),
|
||||||
.finish())
|
message: "Post successfully added.".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
actix_flash::Response::with_redirect(flash, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/{id}")]
|
#[get("/{id}")]
|
||||||
@ -122,7 +134,7 @@ async fn update(
|
|||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
id: web::Path<i32>,
|
id: web::Path<i32>,
|
||||||
post_form: web::Form<post::Model>,
|
post_form: web::Form<post::Model>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> actix_flash::Response<HttpResponse, FlashData> {
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
let form = post_form.into_inner();
|
let form = post_form.into_inner();
|
||||||
|
|
||||||
@ -135,13 +147,19 @@ async fn update(
|
|||||||
.await
|
.await
|
||||||
.expect("could not edit post");
|
.expect("could not edit post");
|
||||||
|
|
||||||
Ok(HttpResponse::Found()
|
let flash = FlashData {
|
||||||
.append_header(("location", "/"))
|
kind: "success".to_owned(),
|
||||||
.finish())
|
message: "Post successfully updated.".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
actix_flash::Response::with_redirect(flash, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/delete/{id}")]
|
#[post("/delete/{id}")]
|
||||||
async fn delete(data: web::Data<AppState>, id: web::Path<i32>) -> Result<HttpResponse, Error> {
|
async fn delete(
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
id: web::Path<i32>,
|
||||||
|
) -> actix_flash::Response<HttpResponse, FlashData> {
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
|
|
||||||
let post: post::ActiveModel = Post::find_by_id(id.into_inner())
|
let post: post::ActiveModel = Post::find_by_id(id.into_inner())
|
||||||
@ -153,9 +171,12 @@ async fn delete(data: web::Data<AppState>, id: web::Path<i32>) -> Result<HttpRes
|
|||||||
|
|
||||||
post.delete(conn).await.unwrap();
|
post.delete(conn).await.unwrap();
|
||||||
|
|
||||||
Ok(HttpResponse::Found()
|
let flash = FlashData {
|
||||||
.append_header(("location", "/"))
|
kind: "success".to_owned(),
|
||||||
.finish())
|
message: "Post successfully deleted.".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
actix_flash::Response::with_redirect(flash, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
@ -179,10 +200,11 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let mut listenfd = ListenFd::from_env();
|
let mut listenfd = ListenFd::from_env();
|
||||||
let mut server = HttpServer::new(move || {
|
let mut server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.service(Fs::new("/static", "./static"))
|
|
||||||
.data(state.clone())
|
.data(state.clone())
|
||||||
.wrap(middleware::Logger::default()) // enable logger
|
.wrap(middleware::Logger::default()) // enable logger
|
||||||
|
.wrap(actix_flash::Flash::default())
|
||||||
.configure(init)
|
.configure(init)
|
||||||
|
.service(fs::Files::new("/static", "./static").show_files_listing())
|
||||||
});
|
});
|
||||||
|
|
||||||
server = match listenfd.take_tcp_listener(0)? {
|
server = match listenfd.take_tcp_listener(0)? {
|
@ -1,3 +0,0 @@
|
|||||||
HOST=127.0.0.1
|
|
||||||
PORT=8000
|
|
||||||
DATABASE_URL="mysql://root:root@localhost/actix_example"
|
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sea-orm-actix-example"
|
name = "sea-orm-actix-4-beta-example"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Sam Samai <sam@studio2pi.com.au>"]
|
authors = ["Sam Samai <sam@studio2pi.com.au>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@ -9,15 +9,15 @@ publish = false
|
|||||||
members = [".", "entity", "migration"]
|
members = [".", "entity", "migration"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-http = "2"
|
actix-files = "0.6"
|
||||||
actix-web = "3"
|
actix-http = "3"
|
||||||
actix-flash = "0.2"
|
actix-rt = "2.7"
|
||||||
actix-files = "0.5"
|
actix-service = "2"
|
||||||
futures = { version = "^0.3" }
|
actix-web = "4"
|
||||||
futures-util = { version = "^0.3" }
|
|
||||||
tera = "1.8.0"
|
tera = "1.15.0"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
listenfd = "0.3.3"
|
listenfd = "0.5"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
entity = { path = "entity" }
|
entity = { path = "entity" }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||

|

|
||||||
|
|
||||||
# Actix with SeaORM example app
|
# Actix 4 with SeaORM example app
|
||||||
|
|
||||||
1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database
|
1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ version = "^0.7.0"
|
|||||||
features = [
|
features = [
|
||||||
"macros",
|
"macros",
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-actix-native-tls",
|
||||||
"sqlx-mysql",
|
"sqlx-mysql",
|
||||||
# "sqlx-postgres",
|
# "sqlx-postgres",
|
||||||
# "sqlx-sqlite",
|
# "sqlx-sqlite",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use actix_files as fs;
|
use actix_files::Files as Fs;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
error, get, middleware, post, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result,
|
error, get, middleware, post, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result
|
||||||
};
|
};
|
||||||
|
|
||||||
use entity::post;
|
use entity::post;
|
||||||
@ -21,6 +21,7 @@ struct AppState {
|
|||||||
templates: tera::Tera,
|
templates: tera::Tera,
|
||||||
conn: DatabaseConnection,
|
conn: DatabaseConnection,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
page: Option<usize>,
|
page: Option<usize>,
|
||||||
@ -34,11 +35,7 @@ struct FlashData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn list(
|
async fn list(req: HttpRequest, data: web::Data<AppState>) -> Result<HttpResponse, Error> {
|
||||||
req: HttpRequest,
|
|
||||||
data: web::Data<AppState>,
|
|
||||||
opt_flash: Option<actix_flash::Message<FlashData>>,
|
|
||||||
) -> Result<HttpResponse, Error> {
|
|
||||||
let template = &data.templates;
|
let template = &data.templates;
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
|
|
||||||
@ -62,11 +59,6 @@ async fn list(
|
|||||||
ctx.insert("posts_per_page", &posts_per_page);
|
ctx.insert("posts_per_page", &posts_per_page);
|
||||||
ctx.insert("num_pages", &num_pages);
|
ctx.insert("num_pages", &num_pages);
|
||||||
|
|
||||||
if let Some(flash) = opt_flash {
|
|
||||||
let flash_inner = flash.into_inner();
|
|
||||||
ctx.insert("flash", &flash_inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = template
|
let body = template
|
||||||
.render("index.html.tera", &ctx)
|
.render("index.html.tera", &ctx)
|
||||||
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
|
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
|
||||||
@ -87,7 +79,7 @@ async fn new(data: web::Data<AppState>) -> Result<HttpResponse, Error> {
|
|||||||
async fn create(
|
async fn create(
|
||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
post_form: web::Form<post::Model>,
|
post_form: web::Form<post::Model>,
|
||||||
) -> actix_flash::Response<HttpResponse, FlashData> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
|
|
||||||
let form = post_form.into_inner();
|
let form = post_form.into_inner();
|
||||||
@ -101,12 +93,9 @@ async fn create(
|
|||||||
.await
|
.await
|
||||||
.expect("could not insert post");
|
.expect("could not insert post");
|
||||||
|
|
||||||
let flash = FlashData {
|
Ok(HttpResponse::Found()
|
||||||
kind: "success".to_owned(),
|
.append_header(("location", "/"))
|
||||||
message: "Post successfully added.".to_owned(),
|
.finish())
|
||||||
};
|
|
||||||
|
|
||||||
actix_flash::Response::with_redirect(flash, "/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/{id}")]
|
#[get("/{id}")]
|
||||||
@ -134,7 +123,7 @@ async fn update(
|
|||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
id: web::Path<i32>,
|
id: web::Path<i32>,
|
||||||
post_form: web::Form<post::Model>,
|
post_form: web::Form<post::Model>,
|
||||||
) -> actix_flash::Response<HttpResponse, FlashData> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
let form = post_form.into_inner();
|
let form = post_form.into_inner();
|
||||||
|
|
||||||
@ -147,19 +136,13 @@ async fn update(
|
|||||||
.await
|
.await
|
||||||
.expect("could not edit post");
|
.expect("could not edit post");
|
||||||
|
|
||||||
let flash = FlashData {
|
Ok(HttpResponse::Found()
|
||||||
kind: "success".to_owned(),
|
.append_header(("location", "/"))
|
||||||
message: "Post successfully updated.".to_owned(),
|
.finish())
|
||||||
};
|
|
||||||
|
|
||||||
actix_flash::Response::with_redirect(flash, "/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/delete/{id}")]
|
#[post("/delete/{id}")]
|
||||||
async fn delete(
|
async fn delete(data: web::Data<AppState>, id: web::Path<i32>) -> Result<HttpResponse, Error> {
|
||||||
data: web::Data<AppState>,
|
|
||||||
id: web::Path<i32>,
|
|
||||||
) -> actix_flash::Response<HttpResponse, FlashData> {
|
|
||||||
let conn = &data.conn;
|
let conn = &data.conn;
|
||||||
|
|
||||||
let post: post::ActiveModel = Post::find_by_id(id.into_inner())
|
let post: post::ActiveModel = Post::find_by_id(id.into_inner())
|
||||||
@ -171,12 +154,9 @@ async fn delete(
|
|||||||
|
|
||||||
post.delete(conn).await.unwrap();
|
post.delete(conn).await.unwrap();
|
||||||
|
|
||||||
let flash = FlashData {
|
Ok(HttpResponse::Found()
|
||||||
kind: "success".to_owned(),
|
.append_header(("location", "/"))
|
||||||
message: "Post successfully deleted.".to_owned(),
|
.finish())
|
||||||
};
|
|
||||||
|
|
||||||
actix_flash::Response::with_redirect(flash, "/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
@ -191,20 +171,23 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let port = env::var("PORT").expect("PORT is not set in .env file");
|
let port = env::var("PORT").expect("PORT is not set in .env file");
|
||||||
let server_url = format!("{}:{}", host, port);
|
let server_url = format!("{}:{}", host, port);
|
||||||
|
|
||||||
// create post table if not exists
|
// establish connection to database and apply migrations
|
||||||
|
// -> create post table if not exists
|
||||||
let conn = sea_orm::Database::connect(&db_url).await.unwrap();
|
let conn = sea_orm::Database::connect(&db_url).await.unwrap();
|
||||||
Migrator::up(&conn, None).await.unwrap();
|
Migrator::up(&conn, None).await.unwrap();
|
||||||
|
|
||||||
|
// load tera templates and build app state
|
||||||
let templates = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
let templates = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
||||||
let state = AppState { templates, conn };
|
let state = AppState { templates, conn };
|
||||||
|
|
||||||
|
// create server and try to serve over socket if possible
|
||||||
let mut listenfd = ListenFd::from_env();
|
let mut listenfd = ListenFd::from_env();
|
||||||
let mut server = HttpServer::new(move || {
|
let mut server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.data(state.clone())
|
.service(Fs::new("/static", "./static"))
|
||||||
|
.app_data(web::Data::new(state.clone()))
|
||||||
.wrap(middleware::Logger::default()) // enable logger
|
.wrap(middleware::Logger::default()) // enable logger
|
||||||
.wrap(actix_flash::Flash::default())
|
|
||||||
.configure(init)
|
.configure(init)
|
||||||
.service(fs::Files::new("/static", "./static").show_files_listing())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server = match listenfd.take_tcp_listener(0)? {
|
server = match listenfd.take_tcp_listener(0)? {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user