mirror of
https://github.com/tokio-rs/axum.git
synced 2025-03-13 19:27:53 +01:00
Remove tower from axum's public API (#229)
Instead rely on `tower-service` and `tower-layer`. `tower` itself is only used internally. Fixes https://github.com/tokio-rs/axum/issues/186
This commit is contained in:
parent
35ea7ca0ff
commit
f8a0d81d79
27 changed files with 102 additions and 50 deletions
|
@ -47,6 +47,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167))
|
||||
- `Router::check_infallible` now returns a `CheckInfallible` service. This
|
||||
is to improve compile times.
|
||||
- `Router::into_make_service` now returns `routing::IntoMakeService` rather than
|
||||
`tower::make::Shared` ([#229](https://github.com/tokio-rs/axum/pull/229))
|
||||
- All usage of `tower::BoxError` has been replaced with `axum::BoxError` ([#229](https://github.com/tokio-rs/axum/pull/229))
|
||||
- `tower::util::Either` no longer implements `IntoResponse` ([#229](https://github.com/tokio-rs/axum/pull/229))
|
||||
- These future types have been moved
|
||||
- `extract::extractor_middleware::ExtractorMiddlewareResponseFuture` moved
|
||||
to `extract::extractor_middleware::future::ResponseFuture` ([#133](https://github.com/tokio-rs/axum/pull/133))
|
||||
|
|
|
@ -36,6 +36,8 @@ serde_urlencoded = "0.7"
|
|||
tokio = { version = "1", features = ["time"] }
|
||||
tokio-util = "0.6"
|
||||
tower = { version = "0.4", default-features = false, features = ["util", "buffer", "make"] }
|
||||
tower-service = "0.3"
|
||||
tower-layer = "0.3"
|
||||
tower-http = { version = "0.1", features = ["add-extension", "map-response-body"] }
|
||||
sync_wrapper = "0.1.1"
|
||||
|
||||
|
@ -56,6 +58,7 @@ uuid = { version = "0.8", features = ["serde", "v4"] }
|
|||
tokio-stream = "0.1"
|
||||
|
||||
[dev-dependencies.tower]
|
||||
package = "tower"
|
||||
version = "0.4"
|
||||
features = [
|
||||
"util",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! HTTP body utilities.
|
||||
|
||||
use crate::BoxError;
|
||||
use crate::Error;
|
||||
use tower::BoxError;
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use http_body::{Body as HttpBody, Empty, Full};
|
||||
|
|
|
@ -8,7 +8,8 @@ use std::{
|
|||
};
|
||||
use tokio::sync::{mpsc, oneshot, OwnedSemaphorePermit, Semaphore};
|
||||
use tokio_util::sync::PollSemaphore;
|
||||
use tower::{Service, ServiceExt};
|
||||
use tower::ServiceExt;
|
||||
use tower_service::Service;
|
||||
|
||||
/// A version of [`tower::buffer::Buffer`] which panicks on channel related errors, thus keeping
|
||||
/// the error type of the service.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::BoxError;
|
||||
use std::{error::Error as StdError, fmt};
|
||||
use tower::BoxError;
|
||||
|
||||
/// Errors that can happen when using axum.
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -14,8 +14,8 @@ use std::{
|
|||
net::SocketAddr,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::Service;
|
||||
use tower_http::add_extension::AddExtension;
|
||||
use tower_service::Service;
|
||||
|
||||
/// A [`MakeService`] created from a router.
|
||||
///
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//! See [`extractor_middleware`] for more details.
|
||||
|
||||
use super::{FromRequest, RequestParts};
|
||||
use crate::BoxError;
|
||||
use crate::{body::BoxBody, response::IntoResponse};
|
||||
use bytes::Bytes;
|
||||
use futures_util::{future::BoxFuture, ready};
|
||||
|
@ -15,7 +16,8 @@ use std::{
|
|||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{BoxError, Layer, Service};
|
||||
use tower_layer::Layer;
|
||||
use tower_service::Service;
|
||||
|
||||
/// Convert an extractor into a middleware.
|
||||
///
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use super::{has_content_type, rejection::*, take_body, FromRequest, RequestParts};
|
||||
use crate::BoxError;
|
||||
use async_trait::async_trait;
|
||||
use bytes::Buf;
|
||||
use http::Method;
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::ops::Deref;
|
||||
use tower::BoxError;
|
||||
|
||||
/// Extractor that deserializes `application/x-www-form-urlencoded` requests
|
||||
/// into some type.
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//! See [`Multipart`] for more details.
|
||||
|
||||
use super::{rejection::*, BodyStream, FromRequest, RequestParts};
|
||||
use crate::BoxError;
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use futures_util::stream::Stream;
|
||||
|
@ -13,7 +14,6 @@ use std::{
|
|||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::BoxError;
|
||||
|
||||
/// Extractor that parses `multipart/form-data` requests commonly used with file uploads.
|
||||
///
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! Rejection response types.
|
||||
|
||||
use super::IntoResponse;
|
||||
use crate::BoxError;
|
||||
use crate::{
|
||||
body::{box_body, BoxBody},
|
||||
Error,
|
||||
|
@ -8,7 +9,6 @@ use crate::{
|
|||
use bytes::Bytes;
|
||||
use http_body::Full;
|
||||
use std::convert::Infallible;
|
||||
use tower::BoxError;
|
||||
|
||||
define_rejection! {
|
||||
#[status = INTERNAL_SERVER_ERROR]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{rejection::*, take_body, Extension, FromRequest, RequestParts};
|
||||
use crate::BoxError;
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use futures_util::stream::Stream;
|
||||
|
@ -8,7 +9,6 @@ use std::{
|
|||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::BoxError;
|
||||
|
||||
#[async_trait]
|
||||
impl<B> FromRequest<B> for Request<B>
|
||||
|
|
|
@ -16,7 +16,8 @@ use std::{
|
|||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{util::Oneshot, Service};
|
||||
use tower::util::Oneshot;
|
||||
use tower_service::Service;
|
||||
|
||||
pin_project! {
|
||||
/// The response future for [`OnMethod`](super::OnMethod).
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
marker::PhantomData,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::Service;
|
||||
use tower_service::Service;
|
||||
|
||||
/// An adapter that makes a [`Handler`] into a [`Service`].
|
||||
///
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
|||
routing::{EmptyRouter, MethodFilter},
|
||||
service::HandleError,
|
||||
util::Either,
|
||||
BoxError,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
|
@ -18,7 +19,9 @@ use std::{
|
|||
marker::PhantomData,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{BoxError, Layer, Service, ServiceExt};
|
||||
use tower::ServiceExt;
|
||||
use tower_layer::Layer;
|
||||
use tower_service::Service;
|
||||
|
||||
pub mod future;
|
||||
mod into_service;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::BoxError;
|
||||
use crate::{
|
||||
extract::{has_content_type, rejection::*, take_body, FromRequest, RequestParts},
|
||||
response::IntoResponse,
|
||||
|
@ -15,7 +16,6 @@ use std::{
|
|||
convert::Infallible,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
use tower::BoxError;
|
||||
|
||||
/// JSON Extractor/Response
|
||||
///
|
||||
|
|
|
@ -832,3 +832,6 @@ pub use tower_http::add_extension::{AddExtension, AddExtensionLayer};
|
|||
|
||||
#[doc(inline)]
|
||||
pub use self::{error::Error, json::Json, routing::Router};
|
||||
|
||||
/// Alias for a type-erased error type.
|
||||
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
|
|
@ -81,7 +81,7 @@ macro_rules! define_rejection {
|
|||
impl $name {
|
||||
pub(crate) fn from_err<E>(err: E) -> Self
|
||||
where
|
||||
E: Into<tower::BoxError>,
|
||||
E: Into<crate::BoxError>,
|
||||
{
|
||||
Self(crate::Error::new(err))
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use super::IntoResponse;
|
||||
use crate::body::{box_body, BoxBody};
|
||||
use crate::{
|
||||
body::{box_body, BoxBody},
|
||||
BoxError,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use http::header::{HeaderMap, HeaderName, HeaderValue};
|
||||
use http::{Response, StatusCode};
|
||||
use http_body::{Body, Full};
|
||||
use std::{convert::TryInto, fmt};
|
||||
use tower::{util::Either, BoxError};
|
||||
use tower::util::Either;
|
||||
|
||||
/// A response with headers.
|
||||
///
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use crate::{
|
||||
body::{box_body, BoxBody},
|
||||
Error,
|
||||
BoxError, Error,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use http::{header, HeaderMap, HeaderValue, Response, StatusCode};
|
||||
|
@ -11,7 +11,6 @@ use http_body::{
|
|||
Empty, Full,
|
||||
};
|
||||
use std::{borrow::Cow, convert::Infallible};
|
||||
use tower::{util::Either, BoxError};
|
||||
|
||||
mod headers;
|
||||
mod redirect;
|
||||
|
@ -154,22 +153,6 @@ impl IntoResponse for Infallible {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, K> IntoResponse for Either<T, K>
|
||||
where
|
||||
T: IntoResponse,
|
||||
K: IntoResponse,
|
||||
{
|
||||
type Body = BoxBody;
|
||||
type BodyError = Error;
|
||||
|
||||
fn into_response(self) -> Response<Self::Body> {
|
||||
match self {
|
||||
Either::A(inner) => inner.into_response().map(box_body),
|
||||
Either::B(inner) => inner.into_response().map(box_body),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> IntoResponse for Result<T, E>
|
||||
where
|
||||
T: IntoResponse,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
//! ```
|
||||
|
||||
use crate::response::IntoResponse;
|
||||
use crate::BoxError;
|
||||
use bytes::Bytes;
|
||||
use futures_util::{
|
||||
ready,
|
||||
|
@ -48,7 +49,6 @@ use std::{
|
|||
};
|
||||
use sync_wrapper::SyncWrapper;
|
||||
use tokio::time::Sleep;
|
||||
use tower::BoxError;
|
||||
|
||||
/// Create a new [`Sse`] response that will respond with the given stream of
|
||||
/// [`Event`]s.
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
//! Future types.
|
||||
|
||||
use crate::{body::BoxBody, buffer::MpscBuffer, routing::FromEmptyRouter};
|
||||
use crate::{body::BoxBody, buffer::MpscBuffer, routing::FromEmptyRouter, BoxError};
|
||||
use futures_util::ready;
|
||||
use http::{Request, Response};
|
||||
use pin_project_lite::pin_project;
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
fmt,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
|
@ -12,8 +13,9 @@ use std::{
|
|||
};
|
||||
use tower::{
|
||||
util::{BoxService, Oneshot},
|
||||
BoxError, Service, ServiceExt,
|
||||
ServiceExt,
|
||||
};
|
||||
use tower_service::Service;
|
||||
|
||||
pub use super::or::ResponseFuture as OrResponseFuture;
|
||||
|
||||
|
@ -179,3 +181,9 @@ where
|
|||
self.project().inner.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
opaque_future! {
|
||||
/// Response future from [`MakeRouteService`] services.
|
||||
pub type MakeRouteServiceFuture<S> =
|
||||
futures_util::future::Ready<Result<S, Infallible>>;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::{
|
|||
},
|
||||
service::HandleError,
|
||||
util::ByteStr,
|
||||
BoxError,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use http::{Request, Response, StatusCode, Uri};
|
||||
|
@ -24,17 +25,19 @@ use std::{
|
|||
};
|
||||
use tower::{
|
||||
util::{BoxService, ServiceExt},
|
||||
BoxError, Layer, Service, ServiceBuilder,
|
||||
ServiceBuilder,
|
||||
};
|
||||
use tower_http::map_response_body::MapResponseBodyLayer;
|
||||
use tower_layer::Layer;
|
||||
use tower_service::Service;
|
||||
|
||||
pub mod future;
|
||||
|
||||
mod method_filter;
|
||||
mod or;
|
||||
|
||||
pub use self::{method_filter::MethodFilter, or::Or};
|
||||
|
||||
mod method_filter;
|
||||
|
||||
/// The router type for composing handlers and services.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Router<S> {
|
||||
|
@ -358,11 +361,11 @@ impl<S> Router<S> {
|
|||
/// ```
|
||||
///
|
||||
/// [`MakeService`]: tower::make::MakeService
|
||||
pub fn into_make_service(self) -> tower::make::Shared<S>
|
||||
pub fn into_make_service(self) -> IntoMakeService<S>
|
||||
where
|
||||
S: Clone,
|
||||
{
|
||||
tower::make::Shared::new(self.svc)
|
||||
IntoMakeService::new(self.svc)
|
||||
}
|
||||
|
||||
/// Convert this router into a [`MakeService`], that will store `C`'s
|
||||
|
@ -1019,6 +1022,39 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A [`MakeService`] that produces axum router services.
|
||||
///
|
||||
/// [`MakeService`]: tower::make::MakeService
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IntoMakeService<S> {
|
||||
service: S,
|
||||
}
|
||||
|
||||
impl<S> IntoMakeService<S> {
|
||||
fn new(service: S) -> Self {
|
||||
Self { service }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> Service<T> for IntoMakeService<S>
|
||||
where
|
||||
S: Clone,
|
||||
{
|
||||
type Response = S;
|
||||
type Error = Infallible;
|
||||
type Future = future::MakeRouteServiceFuture<S>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, _target: T) -> Self::Future {
|
||||
future::MakeRouteServiceFuture {
|
||||
future: futures_util::future::ready(Ok(self.service.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -10,7 +10,8 @@ use std::{
|
|||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{util::Oneshot, Service, ServiceExt};
|
||||
use tower::{util::Oneshot, ServiceExt};
|
||||
use tower_service::Service;
|
||||
|
||||
/// [`tower::Service`] that is the combination of two routers.
|
||||
///
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
|||
body::{box_body, BoxBody},
|
||||
response::IntoResponse,
|
||||
util::{Either, EitherProj},
|
||||
BoxError,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use futures_util::ready;
|
||||
|
@ -15,7 +16,8 @@ use std::{
|
|||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{util::Oneshot, BoxError, Service};
|
||||
use tower::util::Oneshot;
|
||||
use tower_service::Service;
|
||||
|
||||
pin_project! {
|
||||
/// Response future for [`HandleError`](super::HandleError).
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
//! [`Redirect`]: tower_http::services::Redirect
|
||||
//! [load shed]: tower::load_shed
|
||||
|
||||
use crate::BoxError;
|
||||
use crate::{
|
||||
body::BoxBody,
|
||||
response::IntoResponse,
|
||||
|
@ -108,7 +109,8 @@ use std::{
|
|||
marker::PhantomData,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{util::Oneshot, BoxError, Service, ServiceExt as _};
|
||||
use tower::{util::Oneshot, ServiceExt as _};
|
||||
use tower_service::Service;
|
||||
|
||||
pub mod future;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![allow(clippy::blacklisted_name)]
|
||||
|
||||
use crate::BoxError;
|
||||
use crate::{
|
||||
extract,
|
||||
handler::{any, delete, get, on, patch, post, Handler},
|
||||
|
@ -23,7 +24,8 @@ use std::{
|
|||
task::{Context, Poll},
|
||||
time::Duration,
|
||||
};
|
||||
use tower::{make::Shared, service_fn, BoxError, Service};
|
||||
use tower::{make::Shared, service_fn};
|
||||
use tower_service::Service;
|
||||
|
||||
mod get_to_head;
|
||||
mod handle_error;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
use super::*;
|
||||
use crate::{extract::OriginalUri, response::IntoResponse, Json};
|
||||
use serde_json::{json, Value};
|
||||
use tower::{limit::ConcurrencyLimitLayer, timeout::TimeoutLayer};
|
||||
|
||||
use crate::{extract::OriginalUri, response::IntoResponse, Json};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn basic() {
|
||||
let one = Router::new()
|
||||
|
|
Loading…
Add table
Reference in a new issue