With the growing of the server functions, the code which prepare multiply infrastructures for the server in the main become more and more complex.
For example, I need connect to Mysql
and Redis
, start MessageQuery
, start GracefulShutdown and so on.
In other to simplify the start up code with my server project, there comes the axum-starter
The following example using axum-starter
starting a web server which
server on http://127.0.0.1:8080
It can do
simple_logger
and adding TraceLayer as logger middlewarehttp://127.0.0.1:8080/{name}
will respond greet with your namectrl + c
can graceful stop the server```rust
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use axum::{extract::Path, routing::get}; use axumstarter::{ graceful::SetGraceful, prepare, router::Route, PreparedEffect, Provider, ServeAddress, ServerEffect, ServerPrepare, }; use futures::FutureExt; use tokio::sync::oneshot; use towerhttp::trace::TraceLayer;
/// configure for server starter
struct Configure { #[provider(ref, transparent)] foo: String, #[provider(skip)] bar: SocketAddr,
foo_bar: (i32, i32),
}
impl ServeAddress for Configure { type Address = SocketAddr;
fn get_address(&self) -> Self::Address {
self.bar
}
}
impl ServerEffect for Configure {}
impl Configure { pub fn new() -> Self { Self { foo: "Foo".into(), bar: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080)), foo_bar: (1, 2), } } } // prepares
/// using #[prepare]
fn startlogger() -> Result<(), log::SetLoggerError> { simplelogger::init() }
/// if need ref args ,adding a lifetime
fn show_foo(foo: &'arg String) { println!("this is Foo {foo}") }
fn echo() -> impl PreparedEffect {
Route::new(
"/:echo",
get(|Path(echo): Path
async fn show(FooBar((x, y)): FooBar) { println!("the foo bar is local at ({x}, {y})") }
/// function style prepare async fn gracefulshutdown() -> impl PreparedEffect { let (tx, rx) = oneshot::channel(); tokio::spawn(async move { match tokio::signal::ctrlc().await { _ => { println!("recv ctrl c"); tx.send(()) } } }); tokio::task::yield_now().await;
SetGraceful::new(rx.map(|_| ()))
}
async fn main() { start().await }
async fn start() { ServerPrepare::withconfig(Configure::new()) .append(Logger) .append(ShowFoo) .appendfn(show) .appendfn(gracefulshutdown) .append(EchoRouter) .withglobalmiddleware(TraceLayer::newforhttp()) .prepare_start() .await .expect("Prepare for starting server failure") .launch() .await .expect("Server Error") }
```
Prepare
traitthe trait define how to apply the prepare task,
after prepare down, it return a PreparedEffect
PreparedEffect
traitthe trait will apply multiply effect on the server. include the following
hyper::Server