Crate axum_starter
source · [−]Expand description
Axum Starter
Why axum-starter
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
Quick Start
The following example using axum-starter
starting a web server which
server on http://127.0.0.1:8080
It can do
- show info before launch
- using
simple_logger
and adding TraceLayer as logger middleware - request
http://127.0.0.1:8080/{name}
will respond greet with your name - using
ctrl + c
can graceful stop the server
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use axum::{extract::Path, routing::get};
use axum_starter::{
graceful::SetGraceful, prepare, router::Route, PreparedEffect, Provider, ServeAddress,
ServerEffect, ServerPrepare,
};
use futures::FutureExt;
use tokio::sync::oneshot;
use tower_http::trace::TraceLayer;
/// configure for server starter
#[derive(Debug, Provider)]
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]`
#[prepare(Logger)]
fn start_logger() -> Result<(), log::SetLoggerError> {
simple_logger::init()
}
/// if need ref args ,adding a lifetime
#[prepare(ShowFoo 'arg)]
fn show_foo(foo: &'arg String) {
println!("this is Foo {foo}")
}
#[prepare(EchoRouter)]
fn echo() -> impl PreparedEffect {
Route::new(
"/:echo",
get(|Path(echo): Path<String>| async move { format!("Welcome ! {echo}") }),
)
}
async fn show(FooBar((x, y)): FooBar) {
println!("the foo bar is local at ({x}, {y})")
}
/// function style prepare
async fn graceful_shutdown() -> impl PreparedEffect {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
match tokio::signal::ctrl_c().await {
_ => {
println!("recv ctrl c");
tx.send(())
}
}
});
tokio::task::yield_now().await;
SetGraceful::new(rx.map(|_| ()))
}
#[tokio::main]
async fn main() {
start().await
}
async fn start() {
ServerPrepare::with_config(Configure::new())
.append(Logger)
.append(ShowFoo)
.append_fn(show)
.append_fn(graceful_shutdown)
.append(EchoRouter)
.with_global_middleware(TraceLayer::new_for_http())
.prepare_start()
.await
.expect("Prepare for starting server failure")
.launch()
.await
.expect("Server Error")
}
Prepare
trait
the trait define how to apply the prepare task,
after prepare down, it return a PreparedEffect
PreparedEffect
trait
the trait will apply multiply effect on the server. include the following
- Router
- Extension
- GracefulShutdown
- setting the internal
hyper::Server
Modules
help type for apply effect on adding extension
help type for apply effect on graceful shutdown
Structs
A help type for adding extension
type for prepare starting
Enums
all prepare task are done , the server is ready for launch
Traits
fallible prepare effect
Preparing before server launch
make the func-style Prepare can be used
side effect after a Prepare
the Config that can provide config info
T
the T can be either returning Ownership or Referenceget the address this server are going to bind with
change the server configure, this operate can overwrite
PrepareEffect
Functions
help function for wrap function into PrepareHandler
Type Definitions
Attribute Macros
make a function can apply as a
Prepare
Derive Macros
implement
Provider<T>
for each field of the struct