code: improving server setup code with more admin routes, display correct admin address
This commit is contained in:
parent
c8aefcc0bb
commit
d09bfa6da0
@ -6,8 +6,16 @@ pub mod domain;
|
|||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod views;
|
pub mod views;
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn routes() -> Router<AppState> {
|
pub fn routes() -> Router<AppState> {
|
||||||
Router::new().route("/", get(views::index).post(views::index_action))
|
Router::new()
|
||||||
|
.route("/", get(views::index).post(views::index_action))
|
||||||
|
.route("/app/:app_name", get(views::list_app))
|
||||||
|
.route(
|
||||||
|
"/app/:app_name/:model_name",
|
||||||
|
get(views::list_item_collection),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/app/:app_name/:model_name/detail/:model_id",
|
||||||
|
get(views::item_details),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
@ -11,9 +11,6 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
pub type AdminState = Arc<AdminRegistry>;
|
pub type AdminState = Arc<AdminRegistry>;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub enum RepositoryData {}
|
|
||||||
|
|
||||||
pub trait AdminRepository: Send + Sync {
|
pub trait AdminRepository: Send + Sync {
|
||||||
fn get_item(&self, id: usize) -> Option<Value>;
|
fn get_item(&self, id: usize) -> Option<Value>;
|
||||||
fn get_list(&self) -> Value;
|
fn get_list(&self) -> Value;
|
||||||
@ -61,7 +58,7 @@ impl AdminRegistry {
|
|||||||
AdminApp {
|
AdminApp {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
app_label: label,
|
app_label: label,
|
||||||
app_url: "".to_owned(),
|
app_url: name.to_owned().to_lowercase(),
|
||||||
models: vec![],
|
models: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use axum::extract::Path;
|
||||||
use axum::{extract::State, response::IntoResponse, Form};
|
use axum::{extract::State, response::IntoResponse, Form};
|
||||||
|
|
||||||
use crate::admin::domain::{AdminApp, AdminModel};
|
use crate::admin::domain::{AdminApp, AdminModel};
|
||||||
@ -150,22 +151,41 @@ pub async fn index_action(Form(example_data): Form<ExampleData>) -> impl IntoRes
|
|||||||
"There is your answer!".to_owned()
|
"There is your answer!".to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn list_app(
|
||||||
|
templates: State<templates::Templates>,
|
||||||
|
Path(app_name): Path<String>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
templates.render_html("admin/app_list.html", ())
|
||||||
|
}
|
||||||
|
|
||||||
// List Items renders the entire list item page.
|
// List Items renders the entire list item page.
|
||||||
pub async fn list_item_collection(templates: State<templates::Templates>) -> impl IntoResponse {
|
pub async fn list_item_collection(
|
||||||
|
templates: State<templates::Templates>,
|
||||||
|
Path((app_name, model_name)): Path<(String, String)>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
templates.render_html("admin/items/list_items.html", ())
|
templates.render_html("admin/items/list_items.html", ())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Items Action is a POST to an item list. By default these are actions, that work on a list of items as input.
|
// Items Action is a POST to an item list. By default these are actions, that work on a list of items as input.
|
||||||
pub async fn item_collection_action(Form(question): Form<Question>) -> impl IntoResponse {
|
pub async fn item_collection_action(
|
||||||
|
Form(question): Form<Question>,
|
||||||
|
Path((app_name, model_name)): Path<(String, String)>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
"There is your answer!".to_owned()
|
"There is your answer!".to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item Details shows one single dataset.
|
// Item Details shows one single dataset.
|
||||||
pub async fn item_details(templates: State<templates::Templates>) -> impl IntoResponse {
|
pub async fn item_details(
|
||||||
|
templates: State<templates::Templates>,
|
||||||
|
Path((app_name, model_name, model_id)): Path<(String, String, String)>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
templates.render_html("admin/item_detail.html", ())
|
templates.render_html("admin/item_detail.html", ())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item Action allows running an action on one single dataset.
|
// Item Action allows running an action on one single dataset.
|
||||||
pub async fn item_action(Form(question): Form<Question>) -> impl IntoResponse {
|
pub async fn item_action(
|
||||||
|
Form(question): Form<Question>,
|
||||||
|
Path((app_name, model_name, model_id)): Path<(String, String, String)>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
"There is your answer!".to_owned()
|
"There is your answer!".to_owned()
|
||||||
}
|
}
|
||||||
|
24
src/main.rs
24
src/main.rs
@ -11,7 +11,7 @@ use axum::{
|
|||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use log::info;
|
use log::info;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::net::SocketAddr;
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
async fn home(templates: State<templates::Templates>) -> impl IntoResponse {
|
async fn home(templates: State<templates::Templates>) -> impl IntoResponse {
|
||||||
@ -33,7 +33,7 @@ async fn main() {
|
|||||||
let tmpl = templates::Templates::initialize().expect("Template Engine could not be loaded.");
|
let tmpl = templates::Templates::initialize().expect("Template Engine could not be loaded.");
|
||||||
let mut admin = admin::state::AdminRegistry::new("admin");
|
let mut admin = admin::state::AdminRegistry::new("admin");
|
||||||
admin.register_app("auth", "Authorities", "auth");
|
admin.register_app("auth", "Authorities", "auth");
|
||||||
let admin_router = admin.generate_router();
|
//let admin_router = admin.generate_router();
|
||||||
|
|
||||||
let state: AppState = AppState {
|
let state: AppState = AppState {
|
||||||
templates: tmpl,
|
templates: tmpl,
|
||||||
@ -44,7 +44,8 @@ async fn main() {
|
|||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(home))
|
.route("/", get(home))
|
||||||
.route("/hello", get(hello_world))
|
.route("/hello", get(hello_world))
|
||||||
.merge(admin_router)
|
//.merge(admin_router)
|
||||||
|
.nest("/admin", admin::routes())
|
||||||
.nest("/howto", howto::routes())
|
.nest("/howto", howto::routes())
|
||||||
.route_service("/static/*file", handlers::static_handler.into_service())
|
.route_service("/static/*file", handlers::static_handler.into_service())
|
||||||
.fallback(handlers::not_found_handler)
|
.fallback(handlers::not_found_handler)
|
||||||
@ -52,17 +53,24 @@ async fn main() {
|
|||||||
|
|
||||||
// Run Server
|
// Run Server
|
||||||
let app_host: std::net::IpAddr = env::var("APP_HOST")
|
let app_host: std::net::IpAddr = env::var("APP_HOST")
|
||||||
.unwrap_or("127.0.0.1".to_string())
|
.unwrap_or("0.0.0.0".to_string())
|
||||||
.parse()
|
.parse()
|
||||||
.expect("IP Address expected in APP_HOST");
|
.expect("IP Address expected in APP_HOST");
|
||||||
let app_port: u16 = env::var("APP_PORT")
|
let app_port: u16 = env::var("APP_PORT")
|
||||||
.unwrap_or("3000".to_string())
|
.unwrap_or("3000".to_string())
|
||||||
.parse()
|
.parse()
|
||||||
.expect("Port expected in APP_PORT");
|
.expect("Port expected in APP_PORT");
|
||||||
let addr = SocketAddr::from((app_host, app_port));
|
// the listen_addr is the address we bind to.
|
||||||
info!("listening on {}", addr);
|
let listen_addr = SocketAddr::from((app_host, app_port));
|
||||||
info!("admin on: http://{}/admin", addr);
|
// the server addr is a concrete address the user can connect to.
|
||||||
axum::Server::bind(&addr)
|
let server_addr = if app_host.is_unspecified() {
|
||||||
|
SocketAddr::from(([127, 0, 0, 1], app_port))
|
||||||
|
} else {
|
||||||
|
listen_addr.clone()
|
||||||
|
};
|
||||||
|
info!("listening on {}", listen_addr);
|
||||||
|
info!("admin on: http://{}/admin", server_addr);
|
||||||
|
axum::Server::bind(&listen_addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
.with_graceful_shutdown(shutdown_signal())
|
.with_graceful_shutdown(shutdown_signal())
|
||||||
.await
|
.await
|
||||||
|
Loading…
Reference in New Issue
Block a user