update examples

This commit is contained in:
David Pedersen 2022-07-03 21:47:23 +02:00
parent 02f9ebaee9
commit 16ef59b6ce
38 changed files with 101 additions and 83 deletions

View file

@ -34,7 +34,7 @@ async fn main() {
.data(StarWars::new())
.finish();
let app = Router::new()
let app = Router::without_state()
.route("/", get(graphql_playground).post(graphql_handler))
.layer(Extension(schema));

View file

@ -44,7 +44,7 @@ async fn main() {
let app_state = Arc::new(AppState { user_set, tx });
let app = Router::new()
let app = Router::without_state()
.route("/", get(index))
.route("/websocket", get(websocket_handler))
.layer(Extension(app_state));

View file

@ -29,7 +29,7 @@ async fn main() {
.with(tracing_subscriber::fmt::layer())
.init();
let app = Router::new().route("/", post(handler)).layer(
let app = Router::without_state().route("/", post(handler)).layer(
ServiceBuilder::new()
.map_request_body(body::boxed)
.layer(middleware::from_fn(print_request_body)),
@ -80,17 +80,22 @@ async fn handler(_: PrintRequestBody, body: Bytes) {
struct PrintRequestBody;
#[async_trait]
impl FromRequest<BoxBody> for PrintRequestBody {
impl<S> FromRequest<S, BoxBody> for PrintRequestBody
where
S: Clone + Send + Sync + 'static,
{
type Rejection = Response;
async fn from_request(req: &mut RequestParts<BoxBody>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, BoxBody>) -> Result<Self, Self::Rejection> {
let state = req.state().clone();
let request = Request::from_request(req)
.await
.map_err(|err| err.into_response())?;
let request = buffer_request_body(request).await?;
*req = RequestParts::new(request);
*req = RequestParts::new(state, request);
Ok(Self)
}

View file

@ -7,7 +7,7 @@
use axum::{
http::{HeaderValue, Method},
response::{Html, IntoResponse},
routing::get,
routing::{get, WithState},
Json, Router,
};
use std::net::SocketAddr;
@ -16,12 +16,12 @@ use tower_http::cors::CorsLayer;
#[tokio::main]
async fn main() {
let frontend = async {
let app = Router::new().route("/", get(html));
let app = Router::without_state().route("/", get(html));
serve(app, 3000).await;
};
let backend = async {
let app = Router::new().route("/json", get(json)).layer(
let app = Router::without_state().route("/json", get(json)).layer(
// see https://docs.rs/tower-http/latest/tower_http/cors/index.html
// for more details
//
@ -38,7 +38,7 @@ async fn main() {
tokio::join!(frontend, backend);
}
async fn serve(app: Router, port: u16) {
async fn serve(app: Router<(), WithState>, port: u16) {
let addr = SocketAddr::from(([127, 0, 0, 1], port));
axum::Server::bind(&addr)
.serve(app.into_make_service())

View file

@ -27,7 +27,7 @@ async fn main() {
.init();
// build our application with a route
let app = Router::new().route("/users", post(handler));
let app = Router::without_state().route("/users", post(handler));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
@ -53,17 +53,18 @@ struct User {
struct Json<T>(T);
#[async_trait]
impl<B, T> FromRequest<B> for Json<T>
impl<S, B, T> FromRequest<S, B> for Json<T>
where
// these trait bounds are copied from `impl FromRequest for axum::Json`
T: DeserializeOwned,
B: axum::body::HttpBody + Send,
B::Data: Send,
B::Error: Into<BoxError>,
S: Send,
{
type Rejection = (StatusCode, axum::Json<Value>);
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
match axum::Json::<T>::from_request(req).await {
Ok(value) => Ok(Self(value.0)),
Err(rejection) => {

View file

@ -27,7 +27,7 @@ async fn main() {
.init();
// build our application with a route
let app = Router::new().route("/users/:user_id/teams/:team_id", get(handler));
let app = Router::without_state().route("/users/:user_id/teams/:team_id", get(handler));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
@ -52,15 +52,16 @@ struct Params {
struct Path<T>(T);
#[async_trait]
impl<B, T> FromRequest<B> for Path<T>
impl<S, B, T> FromRequest<S, B> for Path<T>
where
// these trait bounds are copied from `impl FromRequest for axum::extract::path::Path`
T: DeserializeOwned + Send,
B: Send,
S: Send,
{
type Rejection = (StatusCode, axum::Json<PathError>);
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
match axum::extract::Path::<T>::from_request(req).await {
Ok(value) => Ok(Self(value.0)),
Err(rejection) => {

View file

@ -36,7 +36,7 @@ async fn main() {
let user_repo = Arc::new(ExampleUserRepo) as DynUserRepo;
// Build our application with some routes
let app = Router::new()
let app = Router::without_state()
.route("/users/:id", get(users_show))
.route("/users", post(users_create))
// Add our `user_repo` to all request's extensions so handlers can access

View file

@ -19,7 +19,7 @@ async fn main() {
.init();
// build our application with some routes
let app = Router::new().route("/", get(show_form).post(accept_form));
let app = Router::without_state().route("/", get(show_form).post(accept_form));
// run it with hyper
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

View file

@ -5,7 +5,6 @@
//! ```
use axum::{
handler::Handler,
http::StatusCode,
response::{Html, IntoResponse},
routing::get,
@ -24,10 +23,10 @@ async fn main() {
.init();
// build our application with a route
let app = Router::new().route("/", get(handler));
let app = Router::without_state().route("/", get(handler));
// add a fallback service for handling routes to unknown paths
let app = app.fallback(handler_404.into_service());
let app = app.fallback(handler_404);
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

View file

@ -12,7 +12,7 @@ use tokio::signal;
#[tokio::main]
async fn main() {
// build our application with a route
let app = Router::new().route("/", get(handler));
let app = Router::without_state().route("/", get(handler));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

View file

@ -10,7 +10,7 @@ use std::net::SocketAddr;
#[tokio::main]
async fn main() {
// build our application with a route
let app = Router::new().route("/", get(handler));
let app = Router::without_state().route("/", get(handler));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

View file

@ -35,7 +35,7 @@ async fn main() {
.with(tracing_subscriber::fmt::layer())
.init();
let router = Router::new().route("/", get(|| async { "Hello, World!" }));
let router = Router::without_state().route("/", get(|| async { "Hello, World!" }));
let service = tower::service_fn(move |req: Request<Body>| {
let router = router.clone();

View file

@ -62,7 +62,7 @@ async fn main() {
.with(tracing_subscriber::fmt::layer())
.init();
let app = Router::new()
let app = Router::without_state()
.route("/protected", get(protected))
.route("/authorize", post(authorize));
@ -122,13 +122,14 @@ impl AuthBody {
}
#[async_trait]
impl<B> FromRequest<B> for Claims
impl<S, B> FromRequest<S, B> for Claims
where
S: Send,
B: Send,
{
type Rejection = AuthError;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
// Extract the token from the authorization header
let TypedHeader(Authorization(bearer)) =
TypedHeader::<Authorization<Bearer>>::from_request(req)

View file

@ -40,7 +40,7 @@ async fn main() {
.init();
// Build our application by composing routes
let app = Router::new()
let app = Router::without_state()
.route(
"/:key",
// Add compression to `kv_get`
@ -110,7 +110,7 @@ async fn list_keys(Extension(state): Extension<SharedState>) -> String {
.join("\n")
}
fn admin_routes() -> Router {
fn admin_routes() -> Router<()> {
async fn delete_all_keys(Extension(state): Extension<SharedState>) {
state.write().unwrap().db.clear();
}

View file

@ -50,7 +50,7 @@ async fn main() {
let listener = TcpListener::bind("127.0.0.1:3000").await.unwrap();
let mut listener = AddrIncoming::from_listener(listener).unwrap();
let mut app = Router::new()
let mut app = Router::without_state()
.route("/", get(handler))
.into_make_service_with_connect_info::<SocketAddr>();

View file

@ -24,7 +24,7 @@ async fn main() {
.init();
// build our application with some routes
let app = Router::new()
let app = Router::without_state()
.route("/", get(show_form).post(accept_form))
.layer(tower_http::trace::TraceLayer::new_for_http());

View file

@ -45,7 +45,7 @@ async fn main() {
let oauth_client = oauth_client();
let app = Router::new()
let app = Router::without_state()
.route("/", get(index))
.route("/auth/discord", get(discord_auth))
.route("/auth/authorized", get(login_authorized))
@ -205,14 +205,15 @@ impl IntoResponse for AuthRedirect {
}
#[async_trait]
impl<B> FromRequest<B> for User
impl<S, B> FromRequest<S, B> for User
where
S: Send,
B: Send,
{
// If anything goes wrong or no session is found, redirect to the auth page
type Rejection = AuthRedirect;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
let Extension(store) = Extension::<MemoryStore>::from_request(req)
.await
.expect("`MemoryStore` extension is missing");

View file

@ -25,7 +25,7 @@ async fn main() {
.with(tracing_subscriber::fmt::layer())
.init();
let app = Router::new()
let app = Router::without_state()
.route("/", post(|| async move { "Hello from `POST /`" }))
.layer(middleware::from_fn(print_request_response));

View file

@ -35,7 +35,7 @@ async fn main() {
let recorder_handle = setup_metrics_recorder();
let app = Router::new()
let app = Router::without_state()
.route("/fast", get(|| async {}))
.route(
"/slow",

View file

@ -4,7 +4,7 @@
//! cd examples && cargo run -p example-query-params-with-empty-strings
//! ```
use axum::{extract::Query, routing::get, Router};
use axum::{extract::Query, routing::{get, WithState}, Router};
use serde::{de, Deserialize, Deserializer};
use std::{fmt, str::FromStr};
@ -16,8 +16,8 @@ async fn main() {
.unwrap();
}
fn app() -> Router {
Router::new().route("/", get(handler))
fn app() -> Router<(), WithState> {
Router::without_state().route("/", get(handler))
}
async fn handler(Query(params): Query<Params>) -> String {

View file

@ -19,7 +19,7 @@ async fn main() {
tracing_subscriber::fmt::init();
// build our application with a route
let app = Router::new()
let app = Router::without_state()
// `GET /` goes to `root`
.route("/", get(root))
// `POST /users` goes to `create_user`

View file

@ -55,7 +55,7 @@ async fn main() {
.init();
// build the rest service
let rest = Router::new().route("/", get(web_root));
let rest = Router::without_state().route("/", get(web_root));
// build the grpc service
let grpc = GreeterServer::new(GrpcServiceImpl::default());

View file

@ -24,7 +24,7 @@ async fn main() {
let client = Client::new();
let app = Router::new()
let app = Router::without_state()
.route("/", get(handler))
.layer(Extension(client));
@ -57,7 +57,7 @@ async fn handler(
}
async fn server() {
let app = Router::new().route("/", get(|| async { "Hello, world!" }));
let app = Router::without_state().route("/", get(|| async { "Hello, world!" }));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
println!("server listening on {}", addr);

View file

@ -38,7 +38,7 @@ async fn main() {
// `MemoryStore` just used as an example. Don't use this in production.
let store = MemoryStore::new();
let app = Router::new()
let app = Router::without_state()
.route("/", get(handler))
.layer(Extension(store));
@ -82,13 +82,14 @@ enum UserIdFromSession {
}
#[async_trait]
impl<B> FromRequest<B> for UserIdFromSession
impl<S, B> FromRequest<S, B> for UserIdFromSession
where
B: Send,
S: Send,
{
type Rejection = (StatusCode, &'static str);
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
let Extension(store) = Extension::<MemoryStore>::from_request(req)
.await
.expect("`MemoryStore` extension missing");

View file

@ -46,7 +46,7 @@ async fn main() {
.expect("can connect to database");
// build our application with some routes
let app = Router::new()
let app = Router::without_state()
.route(
"/",
get(using_connection_pool_extractor).post(using_connection_extractor),
@ -77,13 +77,14 @@ async fn using_connection_pool_extractor(
struct DatabaseConnection(sqlx::pool::PoolConnection<sqlx::Postgres>);
#[async_trait]
impl<B> FromRequest<B> for DatabaseConnection
impl<S, B> FromRequest<S, B> for DatabaseConnection
where
S: Send,
B: Send,
{
type Rejection = (StatusCode, String);
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
let Extension(pool) = Extension::<PgPool>::from_request(req)
.await
.map_err(internal_error)?;

View file

@ -29,19 +29,19 @@ async fn main() {
let assets_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("assets");
let static_files_service = get_service(
ServeDir::new(assets_dir).append_index_html_on_directories(true),
)
let static_files_service =
get_service(ServeDir::new(assets_dir).append_index_html_on_directories(true))
.handle_error(|error: std::io::Error| async move {
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Unhandled internal error: {}", error),
)
});
})
.state(());
// build our application with a route
let app = Router::new()
.fallback(static_files_service)
let app = Router::without_state()
.fallback_service(static_files_service)
.route("/sse", get(sse_handler))
.layer(TraceLayer::new_for_http());

View file

@ -32,9 +32,13 @@ async fn main() {
// for serving assets directly at the root you can use `tower_http::services::ServeDir`
// as the fallback to a `Router`
let app: _ = Router::new()
let app: _ = Router::without_state()
.route("/foo", get(|| async { "Hi from /foo" }))
.fallback(get_service(ServeDir::new(".")).handle_error(handle_error))
.fallback_service(
get_service(ServeDir::new("."))
.handle_error(handle_error)
.state(()),
)
.layer(TraceLayer::new_for_http());
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

View file

@ -34,7 +34,7 @@ async fn main() {
.await
.expect("failed to create `uploads` directory");
let app = Router::new()
let app = Router::without_state()
.route("/", get(show_form).post(accept_form))
.route("/file/:file_name", post(save_request_body));

View file

@ -25,7 +25,7 @@ async fn main() {
.init();
// build our application with some routes
let app = Router::new().route("/greet/:name", get(greet));
let app = Router::without_state().route("/greet/:name", get(greet));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

View file

@ -5,7 +5,7 @@
//! ```
use axum::{
routing::{get, post},
routing::{get, post, WithState},
Json, Router,
};
use tower_http::trace::TraceLayer;
@ -34,8 +34,8 @@ async fn main() {
/// Having a function that produces our app makes it easy to call it from tests
/// without having to create an HTTP server.
#[allow(dead_code)]
fn app() -> Router {
Router::new()
fn app() -> Router<(), WithState> {
Router::without_state()
.route("/", get(|| async { "Hello, World!" }))
.route(
"/json",

View file

@ -29,7 +29,7 @@ async fn main() {
.await
.unwrap();
let app = Router::new().route("/", get(handler));
let app = Router::without_state().route("/", get(handler));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
println!("listening on {}", addr);

View file

@ -46,7 +46,7 @@ async fn main() {
let db = Db::default();
// Compose the routes
let app = Router::new()
let app = Router::without_state()
.route("/todos", get(todos_index).post(todos_create))
.route("/todos/:id", patch(todos_update).delete(todos_delete))
// Add middleware to all routes

View file

@ -33,7 +33,7 @@ async fn main() {
let pool = Pool::builder().build(manager).await.unwrap();
// build our application with some routes
let app = Router::new()
let app = Router::without_state()
.route(
"/",
get(using_connection_pool_extractor).post(using_connection_extractor),
@ -71,13 +71,14 @@ async fn using_connection_pool_extractor(
struct DatabaseConnection(PooledConnection<'static, PostgresConnectionManager<NoTls>>);
#[async_trait]
impl<B> FromRequest<B> for DatabaseConnection
impl<S, B> FromRequest<S, B> for DatabaseConnection
where
B: Send,
S: Send,
{
type Rejection = (StatusCode, String);
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
let Extension(pool) = Extension::<ConnectionPool>::from_request(req)
.await
.map_err(internal_error)?;

View file

@ -27,7 +27,7 @@ async fn main() {
.init();
// build our application with a route
let app = Router::new()
let app = Router::without_state()
.route("/", get(handler))
// `TraceLayer` is provided by tower-http so you have to add that as a dependency.
// It provides good defaults but is also very customizable.

View file

@ -60,7 +60,7 @@ mod unix {
let uds = UnixListener::bind(path.clone()).unwrap();
tokio::spawn(async {
let app = Router::new().route("/", get(handler));
let app = Router::without_state().route("/", get(handler));
axum::Server::builder(ServerAccept { uds })
.serve(app.into_make_service_with_connect_info::<UdsConnectInfo>())

View file

@ -34,7 +34,7 @@ async fn main() {
.init();
// build our application with a route
let app = Router::new().route("/", get(handler));
let app = Router::without_state().route("/", get(handler));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
@ -60,16 +60,17 @@ async fn handler(ValidatedForm(input): ValidatedForm<NameInput>) -> Html<String>
pub struct ValidatedForm<T>(pub T);
#[async_trait]
impl<T, B> FromRequest<B> for ValidatedForm<T>
impl<T, S, B> FromRequest<S, B> for ValidatedForm<T>
where
T: DeserializeOwned + Validate,
B: http_body::Body + Send,
B::Data: Send,
B::Error: Into<BoxError>,
S: Send,
{
type Rejection = ServerError;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
let Form(value) = Form::<T>::from_request(req).await?;
value.validate()?;
Ok(ValidatedForm(value))

View file

@ -25,7 +25,7 @@ async fn main() {
.init();
// build our application with some routes
let app = Router::new().route("/:version/foo", get(handler));
let app = Router::without_state().route("/:version/foo", get(handler));
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
@ -48,13 +48,14 @@ enum Version {
}
#[async_trait]
impl<B> FromRequest<B> for Version
impl<S, B> FromRequest<S, B> for Version
where
B: Send,
S: Send,
{
type Rejection = Response;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
let params = Path::<HashMap<String, String>>::from_request(req)
.await
.map_err(IntoResponse::into_response)?;

View file

@ -36,15 +36,16 @@ async fn main() {
let assets_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("assets");
// build our application with some routes
let app = Router::new()
.fallback(
let app = Router::without_state()
.fallback_service(
get_service(ServeDir::new(assets_dir).append_index_html_on_directories(true))
.handle_error(|error: std::io::Error| async move {
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Unhandled internal error: {}", error),
)
}),
})
.state(()),
)
// routes are matched from bottom to top, so we have to put `nest` at the
// top since it matches all routes