mirror of
https://github.com/tokio-rs/axum.git
synced 2025-02-18 03:16:33 +01:00
Add tokio feature & make tokio optional for WASM support (#1382)
* add server feature and make tokio and hyper/server and tcp optional * address review comments * don't mention any specific runtimes in the example * sort deps * add `tokio` feature when adding `ws` * don't always pull in tower feature that pulls in tokio io stuff * remove usage of `tokio_cr` * changelog * depend on tokio version that supports wasm * don't make it sound like tokio doesn't support wasm * call out new default feature Co-authored-by: Fisher Darling <fdarlingco@gmail.com> Co-authored-by: David Pedersen <david.pdrsn@gmail.com>
This commit is contained in:
parent
83ba8c3876
commit
31638a2b22
14 changed files with 132 additions and 14 deletions
20
.github/workflows/CI.yml
vendored
20
.github/workflows/CI.yml
vendored
|
@ -209,6 +209,26 @@ jobs:
|
||||||
-p axum-macros
|
-p axum-macros
|
||||||
--target armv5te-unknown-linux-musleabi
|
--target armv5te-unknown-linux-musleabi
|
||||||
|
|
||||||
|
wasm32-unknown-unknown:
|
||||||
|
needs: check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
target: wasm32-unknown-unknown
|
||||||
|
override: true
|
||||||
|
profile: minimal
|
||||||
|
- uses: Swatinem/rust-cache@v1
|
||||||
|
- name: Check
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: check
|
||||||
|
args: >
|
||||||
|
--manifest-path ./examples/simple-router-wasm/Cargo.toml
|
||||||
|
--target wasm32-unknown-unknown
|
||||||
|
|
||||||
dependencies-are-sorted:
|
dependencies-are-sorted:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
|
|
@ -33,9 +33,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
can be nested or merged into a `Router` with the same state type ([#1368])
|
can be nested or merged into a `Router` with the same state type ([#1368])
|
||||||
- **changed:** `Router::nest` now only accepts `Router`s, the general-purpose
|
- **changed:** `Router::nest` now only accepts `Router`s, the general-purpose
|
||||||
`Service` nesting method has been renamed to `nest_service` ([#1368])
|
`Service` nesting method has been renamed to `nest_service` ([#1368])
|
||||||
|
- **added:** Support compiling to WASM. See the `simple-router-wasm` example
|
||||||
|
for more details ([#1382])
|
||||||
|
- **breaking:** New `tokio` default feature needed for WASM support. If you
|
||||||
|
don't need WASM support but have `default_features = false` for other reasons
|
||||||
|
you likely need to re-enable the `tokio` feature ([#1382])
|
||||||
|
|
||||||
[#1368]: https://github.com/tokio-rs/axum/pull/1368
|
[#1368]: https://github.com/tokio-rs/axum/pull/1368
|
||||||
[#1371]: https://github.com/tokio-rs/axum/pull/1371
|
[#1371]: https://github.com/tokio-rs/axum/pull/1371
|
||||||
|
[#1382]: https://github.com/tokio-rs/axum/pull/1382
|
||||||
[#1387]: https://github.com/tokio-rs/axum/pull/1387
|
[#1387]: https://github.com/tokio-rs/axum/pull/1387
|
||||||
[#1389]: https://github.com/tokio-rs/axum/pull/1389
|
[#1389]: https://github.com/tokio-rs/axum/pull/1389
|
||||||
[#1396]: https://github.com/tokio-rs/axum/pull/1396
|
[#1396]: https://github.com/tokio-rs/axum/pull/1396
|
||||||
|
|
|
@ -12,7 +12,7 @@ readme = "README.md"
|
||||||
repository = "https://github.com/tokio-rs/axum"
|
repository = "https://github.com/tokio-rs/axum"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["form", "http1", "json", "matched-path", "original-uri", "query", "tower-log"]
|
default = ["form", "http1", "json", "matched-path", "original-uri", "query", "tokio", "tower-log"]
|
||||||
form = ["dep:serde_urlencoded"]
|
form = ["dep:serde_urlencoded"]
|
||||||
http1 = ["hyper/http1"]
|
http1 = ["hyper/http1"]
|
||||||
http2 = ["hyper/http2"]
|
http2 = ["hyper/http2"]
|
||||||
|
@ -22,8 +22,9 @@ matched-path = []
|
||||||
multipart = ["dep:multer"]
|
multipart = ["dep:multer"]
|
||||||
original-uri = []
|
original-uri = []
|
||||||
query = ["dep:serde_urlencoded"]
|
query = ["dep:serde_urlencoded"]
|
||||||
|
tokio = ["dep:tokio", "hyper/server", "hyper/tcp", "tower/make"]
|
||||||
tower-log = ["tower/log"]
|
tower-log = ["tower/log"]
|
||||||
ws = ["dep:tokio-tungstenite", "dep:sha-1", "dep:base64"]
|
ws = ["tokio", "dep:tokio-tungstenite", "dep:sha-1", "dep:base64"]
|
||||||
|
|
||||||
# Required for intra-doc links to resolve correctly
|
# Required for intra-doc links to resolve correctly
|
||||||
__private_docs = ["tower/full", "tower-http/full"]
|
__private_docs = ["tower/full", "tower-http/full"]
|
||||||
|
@ -36,7 +37,7 @@ bytes = "1.0"
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
|
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
|
||||||
http = "0.2.5"
|
http = "0.2.5"
|
||||||
http-body = "0.4.4"
|
http-body = "0.4.4"
|
||||||
hyper = { version = "0.14.14", features = ["server", "tcp", "stream"] }
|
hyper = { version = "0.14.14", features = ["stream"] }
|
||||||
itoa = "1.0.1"
|
itoa = "1.0.1"
|
||||||
matchit = "0.6"
|
matchit = "0.6"
|
||||||
memchr = "2.4.1"
|
memchr = "2.4.1"
|
||||||
|
@ -45,8 +46,7 @@ percent-encoding = "2.1"
|
||||||
pin-project-lite = "0.2.7"
|
pin-project-lite = "0.2.7"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
sync_wrapper = "0.1.1"
|
sync_wrapper = "0.1.1"
|
||||||
tokio = { version = "1", features = ["time"] }
|
tower = { version = "0.4.13", default-features = false, features = ["util"] }
|
||||||
tower = { version = "0.4.13", default-features = false, features = ["util", "make"] }
|
|
||||||
tower-http = { version = "0.3.0", features = ["util", "map-response-body"] }
|
tower-http = { version = "0.3.0", features = ["util", "map-response-body"] }
|
||||||
tower-layer = "0.3"
|
tower-layer = "0.3"
|
||||||
tower-service = "0.3"
|
tower-service = "0.3"
|
||||||
|
@ -60,6 +60,7 @@ serde_json = { version = "1.0", features = ["raw_value"], optional = true }
|
||||||
serde_path_to_error = { version = "0.1.8", optional = true }
|
serde_path_to_error = { version = "0.1.8", optional = true }
|
||||||
serde_urlencoded = { version = "0.7", optional = true }
|
serde_urlencoded = { version = "0.7", optional = true }
|
||||||
sha-1 = { version = "0.10", optional = true }
|
sha-1 = { version = "0.10", optional = true }
|
||||||
|
tokio = { package = "tokio", version = "1.21", features = ["time"], optional = true }
|
||||||
tokio-tungstenite = { version = "0.17.2", optional = true }
|
tokio-tungstenite = { version = "0.17.2", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -70,7 +71,7 @@ quickcheck_macros = "1.0"
|
||||||
reqwest = { version = "0.11.11", default-features = false, features = ["json", "stream", "multipart"] }
|
reqwest = { version = "0.11.11", default-features = false, features = ["json", "stream", "multipart"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tokio = { version = "1.6.1", features = ["macros", "rt", "rt-multi-thread", "net", "test-util"] }
|
tokio = { package = "tokio", version = "1.21", features = ["macros", "rt", "rt-multi-thread", "net", "test-util"] }
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
uuid = { version = "1.0", features = ["serde", "v4"] }
|
uuid = { version = "1.0", features = ["serde", "v4"] }
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::{extract::connect_info::IntoMakeServiceWithConnectInfo, routing::IntoMakeService};
|
#[cfg(feature = "tokio")]
|
||||||
|
use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||||
|
use crate::routing::IntoMakeService;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
/// Extension trait that adds additional methods to any [`Service`].
|
/// Extension trait that adds additional methods to any [`Service`].
|
||||||
|
@ -26,6 +28,7 @@ pub trait ServiceExt<R>: Service<R> + Sized {
|
||||||
/// ["Rewriting request URI in middleware"]: crate::middleware#rewriting-request-uri-in-middleware
|
/// ["Rewriting request URI in middleware"]: crate::middleware#rewriting-request-uri-in-middleware
|
||||||
/// [`Router`]: crate::Router
|
/// [`Router`]: crate::Router
|
||||||
/// [`ConnectInfo`]: crate::extract::connect_info::ConnectInfo
|
/// [`ConnectInfo`]: crate::extract::connect_info::ConnectInfo
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C>;
|
fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +40,7 @@ where
|
||||||
IntoMakeService::new(self)
|
IntoMakeService::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
|
fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
|
||||||
IntoMakeServiceWithConnectInfo::new(self)
|
IntoMakeServiceWithConnectInfo::new(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use http::header::{self, HeaderMap};
|
use http::header::{self, HeaderMap};
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
pub mod connect_info;
|
pub mod connect_info;
|
||||||
pub mod path;
|
pub mod path;
|
||||||
pub mod rejection;
|
pub mod rejection;
|
||||||
|
@ -23,7 +24,6 @@ pub use axum_macros::{FromRequest, FromRequestParts};
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use self::{
|
pub use self::{
|
||||||
connect_info::ConnectInfo,
|
|
||||||
host::Host,
|
host::Host,
|
||||||
path::Path,
|
path::Path,
|
||||||
raw_query::RawQuery,
|
raw_query::RawQuery,
|
||||||
|
@ -31,6 +31,10 @@ pub use self::{
|
||||||
state::State,
|
state::State,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
pub use self::connect_info::ConnectInfo;
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
pub use crate::Json;
|
pub use crate::Json;
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
//! If you need to read and write concurrently from a [`WebSocket`] you can use
|
//! If you need to read and write concurrently from a [`WebSocket`] you can use
|
||||||
//! [`StreamExt::split`]:
|
//! [`StreamExt::split`]:
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```rust,no_run
|
||||||
//! use axum::{Error, extract::ws::{WebSocket, Message}};
|
//! use axum::{Error, extract::ws::{WebSocket, Message}};
|
||||||
//! use futures::{sink::SinkExt, stream::{StreamExt, SplitSink, SplitStream}};
|
//! use futures::{sink::SinkExt, stream::{StreamExt, SplitSink, SplitStream}};
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -35,9 +35,11 @@
|
||||||
//!
|
//!
|
||||||
#![doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
#![doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||||
use crate::{
|
use crate::{
|
||||||
body::Body,
|
body::Body,
|
||||||
extract::{connect_info::IntoMakeServiceWithConnectInfo, FromRequest, FromRequestParts},
|
extract::{FromRequest, FromRequestParts},
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
routing::IntoMakeService,
|
routing::IntoMakeService,
|
||||||
};
|
};
|
||||||
|
@ -318,6 +320,7 @@ pub trait HandlerWithoutStateExt<T, B>: Handler<T, (), B> {
|
||||||
/// See [`WithState::into_make_service_with_connect_info`] for more details.
|
/// See [`WithState::into_make_service_with_connect_info`] for more details.
|
||||||
///
|
///
|
||||||
/// [`MakeService`]: tower::make::MakeService
|
/// [`MakeService`]: tower::make::MakeService
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
fn into_make_service_with_connect_info<C>(
|
fn into_make_service_with_connect_info<C>(
|
||||||
self,
|
self,
|
||||||
) -> IntoMakeServiceWithConnectInfo<IntoService<Self, T, (), B>, C>;
|
) -> IntoMakeServiceWithConnectInfo<IntoService<Self, T, (), B>, C>;
|
||||||
|
@ -335,6 +338,7 @@ where
|
||||||
self.with_state(()).into_make_service()
|
self.with_state(()).into_make_service()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
fn into_make_service_with_connect_info<C>(
|
fn into_make_service_with_connect_info<C>(
|
||||||
self,
|
self,
|
||||||
) -> IntoMakeServiceWithConnectInfo<IntoService<Self, T, (), B>, C> {
|
) -> IntoMakeServiceWithConnectInfo<IntoService<Self, T, (), B>, C> {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use super::{Handler, IntoService};
|
use super::{Handler, IntoService};
|
||||||
use crate::{extract::connect_info::IntoMakeServiceWithConnectInfo, routing::IntoMakeService};
|
#[cfg(feature = "tokio")]
|
||||||
|
use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||||
|
use crate::routing::IntoMakeService;
|
||||||
use http::Request;
|
use http::Request;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
@ -95,6 +97,7 @@ impl<H, T, S, B> WithState<H, T, S, B> {
|
||||||
///
|
///
|
||||||
/// [`MakeService`]: tower::make::MakeService
|
/// [`MakeService`]: tower::make::MakeService
|
||||||
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
pub fn into_make_service_with_connect_info<C>(
|
pub fn into_make_service_with_connect_info<C>(
|
||||||
self,
|
self,
|
||||||
) -> IntoMakeServiceWithConnectInfo<IntoService<H, T, S, B>, C> {
|
) -> IntoMakeServiceWithConnectInfo<IntoService<H, T, S, B>, C> {
|
||||||
|
|
|
@ -350,6 +350,7 @@
|
||||||
//! `matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | Yes
|
//! `matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | Yes
|
||||||
//! `multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] | No
|
//! `multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] | No
|
||||||
//! `original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | Yes
|
//! `original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | Yes
|
||||||
|
//! `tokio` | Enables `tokio` as a dependency and `axum::Server`, `SSE` and `extract::connect_info` types. | Yes
|
||||||
//! `tower-log` | Enables `tower`'s `log` feature | Yes
|
//! `tower-log` | Enables `tower`'s `log` feature | Yes
|
||||||
//! `ws` | Enables WebSockets support via [`extract::ws`] | No
|
//! `ws` | Enables WebSockets support via [`extract::ws`] | No
|
||||||
//! `form` | Enables the `Form` extractor | Yes
|
//! `form` | Enables the `Form` extractor | Yes
|
||||||
|
@ -461,6 +462,7 @@ pub use async_trait::async_trait;
|
||||||
pub use headers;
|
pub use headers;
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use http;
|
pub use http;
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use hyper::Server;
|
pub use hyper::Server;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use http::{header, HeaderValue};
|
||||||
|
|
||||||
mod redirect;
|
mod redirect;
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
pub mod sse;
|
pub mod sse;
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
|
@ -28,7 +29,11 @@ pub use axum_core::response::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::{redirect::Redirect, sse::Sse};
|
pub use self::redirect::Redirect;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
pub use sse::Sse;
|
||||||
|
|
||||||
/// An HTML response.
|
/// An HTML response.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! Route to services and handlers based on HTTP methods.
|
//! Route to services and handlers based on HTTP methods.
|
||||||
|
|
||||||
use super::IntoMakeService;
|
use super::IntoMakeService;
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||||
use crate::{
|
use crate::{
|
||||||
body::{Body, Bytes, HttpBody},
|
body::{Body, Bytes, HttpBody},
|
||||||
error_handling::{HandleError, HandleErrorLayer},
|
error_handling::{HandleError, HandleErrorLayer},
|
||||||
extract::connect_info::IntoMakeServiceWithConnectInfo,
|
|
||||||
handler::{Handler, IntoServiceStateInExtension},
|
handler::{Handler, IntoServiceStateInExtension},
|
||||||
http::{Method, Request, StatusCode},
|
http::{Method, Request, StatusCode},
|
||||||
response::Response,
|
response::Response,
|
||||||
|
@ -689,6 +690,7 @@ where
|
||||||
///
|
///
|
||||||
/// [`MakeService`]: tower::make::MakeService
|
/// [`MakeService`]: tower::make::MakeService
|
||||||
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
|
pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
|
||||||
IntoMakeServiceWithConnectInfo::new(self)
|
IntoMakeServiceWithConnectInfo::new(self)
|
||||||
}
|
}
|
||||||
|
@ -1186,6 +1188,7 @@ impl<S, B, E> WithState<S, B, E> {
|
||||||
/// See [`MethodRouter::into_make_service_with_connect_info`] for more details.
|
/// See [`MethodRouter::into_make_service_with_connect_info`] for more details.
|
||||||
///
|
///
|
||||||
/// [`MakeService`]: tower::make::MakeService
|
/// [`MakeService`]: tower::make::MakeService
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
|
pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {
|
||||||
IntoMakeServiceWithConnectInfo::new(self)
|
IntoMakeServiceWithConnectInfo::new(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! Routing between [`Service`]s and handlers.
|
//! Routing between [`Service`]s and handlers.
|
||||||
|
|
||||||
use self::not_found::NotFound;
|
use self::not_found::NotFound;
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||||
use crate::{
|
use crate::{
|
||||||
body::{Body, HttpBody},
|
body::{Body, HttpBody},
|
||||||
extract::connect_info::IntoMakeServiceWithConnectInfo,
|
|
||||||
handler::{BoxedHandler, Handler},
|
handler::{BoxedHandler, Handler},
|
||||||
util::try_downcast,
|
util::try_downcast,
|
||||||
Extension,
|
Extension,
|
||||||
|
@ -547,6 +548,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = include_str!("../docs/routing/into_make_service_with_connect_info.md")]
|
#[doc = include_str!("../docs/routing/into_make_service_with_connect_info.md")]
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
pub fn into_make_service_with_connect_info<C>(
|
pub fn into_make_service_with_connect_info<C>(
|
||||||
self,
|
self,
|
||||||
) -> IntoMakeServiceWithConnectInfo<RouterService<B>, C> {
|
) -> IntoMakeServiceWithConnectInfo<RouterService<B>, C> {
|
||||||
|
|
13
examples/simple-router-wasm/Cargo.toml
Normal file
13
examples/simple-router-wasm/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "example-simple-router-wasm"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# `default-features = false` to not depend on tokio features which don't support wasm
|
||||||
|
# you can still pull in tokio manually and only add features that tokio supports for wasm
|
||||||
|
axum = { path = "../../axum", default-features = false }
|
||||||
|
futures-executor = "0.3.21"
|
||||||
|
http = "0.2.7"
|
||||||
|
tower-service = "0.3.1"
|
51
examples/simple-router-wasm/src/main.rs
Normal file
51
examples/simple-router-wasm/src/main.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//! Run with
|
||||||
|
//!
|
||||||
|
//! ```not_rust
|
||||||
|
//! cd examples && cargo run -p example-simple-router-wasm
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! This example shows what using axum in a wasm context might look like. This example should
|
||||||
|
//! always compile with `--target wasm32-unknown-unknown`.
|
||||||
|
//!
|
||||||
|
//! [`mio`](https://docs.rs/mio/latest/mio/index.html), tokio's IO layer, does not support the
|
||||||
|
//! `wasm32-unknown-unknown` target which is why this crate requires `default-features = false`
|
||||||
|
//! for axum.
|
||||||
|
//!
|
||||||
|
//! Most serverless runtimes expect an exported function that takes in a single request and returns
|
||||||
|
//! a single response, much like axum's `Handler` trait. In this example, the handler function is
|
||||||
|
//! `app` with `main` acting as the serverless runtime which originally receives the request and
|
||||||
|
//! calls the app function.
|
||||||
|
//!
|
||||||
|
//! We can use axum's routing, extractors, tower services, and everything else to implement
|
||||||
|
//! our serverless function, even though we are running axum in a wasm context.
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
response::{Html, Response},
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use futures_executor::block_on;
|
||||||
|
use http::Request;
|
||||||
|
use tower_service::Service;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let request: Request<String> = Request::builder()
|
||||||
|
.uri("https://serverless.example/api/")
|
||||||
|
.body("Some Body Data".into())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let response: Response = block_on(app(request));
|
||||||
|
assert_eq!(200, response.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::let_and_return)]
|
||||||
|
async fn app(request: Request<String>) -> Response {
|
||||||
|
let mut router = Router::new().route("/api/", get(index)).into_service();
|
||||||
|
|
||||||
|
let response = router.call(request).await.unwrap();
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index() -> Html<&'static str> {
|
||||||
|
Html("<h1>Hello, World!</h1>")
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue