mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-08 00:00:24 +02:00
Move middleware::from_fn into axum (#719)
* Move `middleware::from_fn` into axum * changelog * fix feature * Rephrase changelog a bit
This commit is contained in:
@@ -8,8 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- **fix:** Depend on tower with `default_features = false` ([#666])
|
- **fix:** Depend on tower with `default_features = false` ([#666])
|
||||||
|
- **change:** `middleware::from_fn` has been deprecated and moved into the main
|
||||||
|
axum crate ([#719])
|
||||||
|
|
||||||
[#666]: https://github.com/tokio-rs/axum/pull/666
|
[#666]: https://github.com/tokio-rs/axum/pull/666
|
||||||
|
[#719]: https://github.com/tokio-rs/axum/pull/719
|
||||||
|
|
||||||
|
# 0.1.2 (13. January, 2021)
|
||||||
|
|
||||||
|
- **fix:** Depend on tower with `default_features = false` ([#666])
|
||||||
|
|
||||||
# 0.1.1 (27. December, 2021)
|
# 0.1.1 (27. December, 2021)
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ http = "0.2"
|
|||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
tower = { version = "0.4", default_features = false, features = ["util"] }
|
tower = { version = "0.4", default_features = false, features = ["util"] }
|
||||||
tower-http = { version = "0.2", features = ["util", "map-response-body"] }
|
tower-http = { version = "0.2", features = ["map-response-body"] }
|
||||||
tower-layer = "0.3"
|
tower-layer = "0.3"
|
||||||
tower-service = "0.3"
|
tower-service = "0.3"
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,5 @@
|
|||||||
#![cfg_attr(test, allow(clippy::float_cmp))]
|
#![cfg_attr(test, allow(clippy::float_cmp))]
|
||||||
|
|
||||||
pub mod extract;
|
pub mod extract;
|
||||||
pub mod middleware;
|
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
//! Additional types for creating middleware.
|
|
||||||
|
|
||||||
pub mod middleware_fn;
|
|
||||||
|
|
||||||
pub use self::middleware_fn::{from_fn, Next};
|
|
||||||
+4
-1
@@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- None.
|
- **added:** `middleware::from_fn` for creating middleware from async functions.
|
||||||
|
This previously lived in axum-extra but has been moved to axum ([#719])
|
||||||
|
|
||||||
|
[#719]: https://github.com/tokio-rs/axum/pull/719
|
||||||
|
|
||||||
# 0.4.5 (31. January, 2022)
|
# 0.4.5 (31. January, 2022)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ sync_wrapper = "0.1.1"
|
|||||||
tokio = { version = "1", features = ["time"] }
|
tokio = { version = "1", features = ["time"] }
|
||||||
tokio-util = "0.6"
|
tokio-util = "0.6"
|
||||||
tower = { version = "0.4.11", default-features = false, features = ["util", "buffer", "make"] }
|
tower = { version = "0.4.11", default-features = false, features = ["util", "buffer", "make"] }
|
||||||
tower-http = { version = "0.2.0", features = ["map-response-body"] }
|
tower-http = { version = "0.2.0", features = ["util", "map-response-body"] }
|
||||||
tower-layer = "0.3"
|
tower-layer = "0.3"
|
||||||
tower-service = "0.3"
|
tower-service = "0.3"
|
||||||
|
|
||||||
|
|||||||
@@ -463,6 +463,7 @@ pub mod body;
|
|||||||
pub mod error_handling;
|
pub mod error_handling;
|
||||||
pub mod extract;
|
pub mod extract;
|
||||||
pub mod handler;
|
pub mod handler;
|
||||||
|
pub mod middleware;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
//! Create middleware from async functions.
|
use crate::{
|
||||||
//!
|
|
||||||
//! See [`from_fn`] for more details.
|
|
||||||
|
|
||||||
use axum::{
|
|
||||||
body::{self, Bytes, HttpBody},
|
body::{self, Bytes, HttpBody},
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
BoxError,
|
BoxError,
|
||||||
@@ -39,8 +35,8 @@ use tower_service::Service;
|
|||||||
/// http::{Request, StatusCode},
|
/// http::{Request, StatusCode},
|
||||||
/// routing::get,
|
/// routing::get,
|
||||||
/// response::IntoResponse,
|
/// response::IntoResponse,
|
||||||
|
/// middleware::{self, Next},
|
||||||
/// };
|
/// };
|
||||||
/// use axum_extra::middleware::{self, Next};
|
|
||||||
///
|
///
|
||||||
/// async fn auth<B>(req: Request<B>, next: Next<B>) -> impl IntoResponse {
|
/// async fn auth<B>(req: Request<B>, next: Next<B>) -> impl IntoResponse {
|
||||||
/// let auth_header = req.headers()
|
/// let auth_header = req.headers()
|
||||||
@@ -76,8 +72,8 @@ use tower_service::Service;
|
|||||||
/// http::{Request, StatusCode},
|
/// http::{Request, StatusCode},
|
||||||
/// routing::get,
|
/// routing::get,
|
||||||
/// response::IntoResponse,
|
/// response::IntoResponse,
|
||||||
|
/// middleware::{self, Next}
|
||||||
/// };
|
/// };
|
||||||
/// use axum_extra::middleware::{self, Next};
|
|
||||||
///
|
///
|
||||||
/// #[derive(Clone)]
|
/// #[derive(Clone)]
|
||||||
/// struct State { /* ... */ }
|
/// struct State { /* ... */ }
|
||||||
@@ -109,9 +105,9 @@ use tower_service::Service;
|
|||||||
/// http::{Request, StatusCode},
|
/// http::{Request, StatusCode},
|
||||||
/// routing::get,
|
/// routing::get,
|
||||||
/// response::IntoResponse,
|
/// response::IntoResponse,
|
||||||
|
/// middleware::{self, Next},
|
||||||
/// AddExtensionLayer,
|
/// AddExtensionLayer,
|
||||||
/// };
|
/// };
|
||||||
/// use axum_extra::middleware::{self, Next};
|
|
||||||
/// use tower::ServiceBuilder;
|
/// use tower::ServiceBuilder;
|
||||||
///
|
///
|
||||||
/// #[derive(Clone)]
|
/// #[derive(Clone)]
|
||||||
@@ -138,37 +134,37 @@ use tower_service::Service;
|
|||||||
/// );
|
/// );
|
||||||
/// # let app: Router = app;
|
/// # let app: Router = app;
|
||||||
/// ```
|
/// ```
|
||||||
pub fn from_fn<F>(f: F) -> MiddlewareFnLayer<F> {
|
pub fn from_fn<F>(f: F) -> FromFnLayer<F> {
|
||||||
MiddlewareFnLayer { f }
|
FromFnLayer { f }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`tower::Layer`] from an async function.
|
/// A [`tower::Layer`] from an async function.
|
||||||
///
|
///
|
||||||
/// [`tower::Layer`] is used to apply middleware to [`axum::Router`]s.
|
/// [`tower::Layer`] is used to apply middleware to [`Router`](crate::Router)'s.
|
||||||
///
|
///
|
||||||
/// Created with [`from_fn`]. See that function for more details.
|
/// Created with [`from_fn`]. See that function for more details.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct MiddlewareFnLayer<F> {
|
pub struct FromFnLayer<F> {
|
||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, F> Layer<S> for MiddlewareFnLayer<F>
|
impl<S, F> Layer<S> for FromFnLayer<F>
|
||||||
where
|
where
|
||||||
F: Clone,
|
F: Clone,
|
||||||
{
|
{
|
||||||
type Service = MiddlewareFn<F, S>;
|
type Service = FromFn<F, S>;
|
||||||
|
|
||||||
fn layer(&self, inner: S) -> Self::Service {
|
fn layer(&self, inner: S) -> Self::Service {
|
||||||
MiddlewareFn {
|
FromFn {
|
||||||
f: self.f.clone(),
|
f: self.f.clone(),
|
||||||
inner,
|
inner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> fmt::Debug for MiddlewareFnLayer<F> {
|
impl<F> fmt::Debug for FromFnLayer<F> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("MiddlewareFnLayer")
|
f.debug_struct("FromFnLayer")
|
||||||
// Write out the type name, without quoting it as `&type_name::<F>()` would
|
// Write out the type name, without quoting it as `&type_name::<F>()` would
|
||||||
.field("f", &format_args!("{}", type_name::<F>()))
|
.field("f", &format_args!("{}", type_name::<F>()))
|
||||||
.finish()
|
.finish()
|
||||||
@@ -179,12 +175,12 @@ impl<F> fmt::Debug for MiddlewareFnLayer<F> {
|
|||||||
///
|
///
|
||||||
/// Created with [`from_fn`]. See that function for more details.
|
/// Created with [`from_fn`]. See that function for more details.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct MiddlewareFn<F, S> {
|
pub struct FromFn<F, S> {
|
||||||
f: F,
|
f: F,
|
||||||
inner: S,
|
inner: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Out, S, ReqBody, ResBody> Service<Request<ReqBody>> for MiddlewareFn<F, S>
|
impl<F, Fut, Out, S, ReqBody, ResBody> Service<Request<ReqBody>> for FromFn<F, S>
|
||||||
where
|
where
|
||||||
F: FnMut(Request<ReqBody>, Next<ReqBody>) -> Fut,
|
F: FnMut(Request<ReqBody>, Next<ReqBody>) -> Fut,
|
||||||
Fut: Future<Output = Out>,
|
Fut: Future<Output = Out>,
|
||||||
@@ -221,12 +217,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, S> fmt::Debug for MiddlewareFn<F, S>
|
impl<F, S> fmt::Debug for FromFn<F, S>
|
||||||
where
|
where
|
||||||
S: fmt::Debug,
|
S: fmt::Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("MiddlewareFnLayer")
|
f.debug_struct("FromFnLayer")
|
||||||
.field("f", &format_args!("{}", type_name::<F>()))
|
.field("f", &format_args!("{}", type_name::<F>()))
|
||||||
.field("inner", &self.inner)
|
.field("inner", &self.inner)
|
||||||
.finish()
|
.finish()
|
||||||
@@ -250,14 +246,14 @@ impl<ReqBody> Next<ReqBody> {
|
|||||||
|
|
||||||
impl<ReqBody> fmt::Debug for Next<ReqBody> {
|
impl<ReqBody> fmt::Debug for Next<ReqBody> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("MiddlewareFnLayer")
|
f.debug_struct("FromFnLayer")
|
||||||
.field("inner", &self.inner)
|
.field("inner", &self.inner)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project! {
|
pin_project! {
|
||||||
/// Response future for [`MiddlewareFn`].
|
/// Response future for [`FromFn`].
|
||||||
pub struct ResponseFuture<F> {
|
pub struct ResponseFuture<F> {
|
||||||
#[pin]
|
#[pin]
|
||||||
inner: F,
|
inner: F,
|
||||||
@@ -283,7 +279,7 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use axum::{body::Empty, routing::get, Router};
|
use crate::{body::Empty, routing::get, Router};
|
||||||
use http::{HeaderMap, StatusCode};
|
use http::{HeaderMap, StatusCode};
|
||||||
use tower::ServiceExt;
|
use tower::ServiceExt;
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
//! Utilities for writing middleware
|
||||||
|
|
||||||
|
mod from_fn;
|
||||||
|
|
||||||
|
pub use self::from_fn::{from_fn, FromFn, FromFnLayer, Next};
|
||||||
@@ -7,11 +7,11 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
body::{Body, Bytes},
|
body::{Body, Bytes},
|
||||||
http::{Request, StatusCode},
|
http::{Request, StatusCode},
|
||||||
|
middleware::{self, Next},
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
routing::post,
|
routing::post,
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use axum_extra::middleware::{self, Next};
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|||||||
@@ -7,8 +7,14 @@
|
|||||||
//! cargo run -p example-prometheus-metrics
|
//! cargo run -p example-prometheus-metrics
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use axum::{extract::MatchedPath, http::Request, response::IntoResponse, routing::get, Router};
|
use axum::{
|
||||||
use axum_extra::middleware::{self, Next};
|
extract::MatchedPath,
|
||||||
|
http::Request,
|
||||||
|
middleware::{self, Next},
|
||||||
|
response::IntoResponse,
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
use metrics_exporter_prometheus::{Matcher, PrometheusBuilder, PrometheusHandle};
|
use metrics_exporter_prometheus::{Matcher, PrometheusBuilder, PrometheusHandle};
|
||||||
use std::{
|
use std::{
|
||||||
future::ready,
|
future::ready,
|
||||||
|
|||||||
Reference in New Issue
Block a user