mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-29 00:00:18 +02:00
Make JSON and HTTP1 support optional (#286)
* Make json support an optional feature * Fix Json type documentation * Make hyper's http1 feature optional
This commit is contained in:
+6
-3
@@ -15,8 +15,10 @@ repository = "https://github.com/tokio-rs/axum"
|
|||||||
members = ["examples/*"]
|
members = ["examples/*"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["tower-log"]
|
default = ["http1", "json", "tower-log"]
|
||||||
|
http1 = ["hyper/http1"]
|
||||||
http2 = ["hyper/http2"]
|
http2 = ["hyper/http2"]
|
||||||
|
json = ["serde_json"]
|
||||||
multipart = ["multer", "mime"]
|
multipart = ["multer", "mime"]
|
||||||
tower-log = ["tower/log"]
|
tower-log = ["tower/log"]
|
||||||
ws = ["tokio-tungstenite", "sha-1", "base64"]
|
ws = ["tokio-tungstenite", "sha-1", "base64"]
|
||||||
@@ -28,11 +30,11 @@ 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"
|
http = "0.2"
|
||||||
http-body = "0.4.3"
|
http-body = "0.4.3"
|
||||||
hyper = { version = "0.14", features = ["server", "tcp", "http1", "stream"] }
|
hyper = { version = "0.14", features = ["server", "tcp", "stream"] }
|
||||||
pin-project-lite = "0.2.7"
|
pin-project-lite = "0.2.7"
|
||||||
regex = "1.5"
|
regex = "1.5"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = { version = "1.0", optional = true }
|
||||||
serde_urlencoded = "0.7"
|
serde_urlencoded = "0.7"
|
||||||
tokio = { version = "1", features = ["time"] }
|
tokio = { version = "1", features = ["time"] }
|
||||||
tokio-util = "0.6"
|
tokio-util = "0.6"
|
||||||
@@ -54,6 +56,7 @@ mime = { optional = true, version = "0.3" }
|
|||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
reqwest = { version = "0.11", features = ["json", "stream"] }
|
reqwest = { version = "0.11", features = ["json", "stream"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
tokio = { version = "1.6.1", features = ["macros", "rt", "rt-multi-thread", "net"] }
|
tokio = { version = "1.6.1", features = ["macros", "rt", "rt-multi-thread", "net"] }
|
||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ pub use self::{
|
|||||||
request_parts::{BodyStream, RawBody},
|
request_parts::{BodyStream, RawBody},
|
||||||
};
|
};
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
|
#[cfg(feature = "json")]
|
||||||
pub use crate::Json;
|
pub use crate::Json;
|
||||||
|
|
||||||
#[cfg(feature = "multipart")]
|
#[cfg(feature = "multipart")]
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ define_rejection! {
|
|||||||
pub struct HeadersAlreadyExtracted;
|
pub struct HeadersAlreadyExtracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "json")]
|
||||||
define_rejection! {
|
define_rejection! {
|
||||||
#[status = BAD_REQUEST]
|
#[status = BAD_REQUEST]
|
||||||
#[body = "Failed to parse the request body as JSON"]
|
#[body = "Failed to parse the request body as JSON"]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||||
/// Rejection type for [`Json`](super::Json).
|
/// Rejection type for [`Json`](super::Json).
|
||||||
pub struct InvalidJsonBody(Error);
|
pub struct InvalidJsonBody(Error);
|
||||||
}
|
}
|
||||||
@@ -199,11 +201,13 @@ composite_rejection! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "json")]
|
||||||
composite_rejection! {
|
composite_rejection! {
|
||||||
/// Rejection used for [`Json`](super::Json).
|
/// Rejection used for [`Json`](super::Json).
|
||||||
///
|
///
|
||||||
/// Contains one variant for each way the [`Json`](super::Json) extractor
|
/// Contains one variant for each way the [`Json`](super::Json) extractor
|
||||||
/// can fail.
|
/// can fail.
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||||
pub enum JsonRejection {
|
pub enum JsonRejection {
|
||||||
InvalidJsonBody,
|
InvalidJsonBody,
|
||||||
MissingJsonContentType,
|
MissingJsonContentType,
|
||||||
|
|||||||
+3
-2
@@ -17,10 +17,10 @@ use std::{
|
|||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// JSON Extractor/Response
|
/// JSON Extractor / Response.
|
||||||
///
|
///
|
||||||
/// When used as an extractor, it can deserialize request bodies into some type that
|
/// When used as an extractor, it can deserialize request bodies into some type that
|
||||||
/// implements [`serde::Serialize`]. If the request body cannot be parsed, or it does not contain
|
/// implements [`serde::Deserialize`]. If the request body cannot be parsed, or it does not contain
|
||||||
/// the `Content-Type: application/json` header, it will reject the request and return a
|
/// the `Content-Type: application/json` header, it will reject the request and return a
|
||||||
/// `400 Bad Request` response.
|
/// `400 Bad Request` response.
|
||||||
///
|
///
|
||||||
@@ -87,6 +87,7 @@ use std::{
|
|||||||
/// # };
|
/// # };
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||||
pub struct Json<T>(pub T);
|
pub struct Json<T>(pub T);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
+8
-1
@@ -1120,7 +1120,10 @@
|
|||||||
//! The following optional features are available:
|
//! The following optional features are available:
|
||||||
//!
|
//!
|
||||||
//! - `headers`: Enables extracting typed headers via [`extract::TypedHeader`].
|
//! - `headers`: Enables extracting typed headers via [`extract::TypedHeader`].
|
||||||
|
//! - `http1`: Enables hyper's `http1` feature. Enabled by default.
|
||||||
//! - `http2`: Enables hyper's `http2` feature.
|
//! - `http2`: Enables hyper's `http2` feature.
|
||||||
|
//! - `json`: Enables the [`Json`] type and some similar convenience functionality.
|
||||||
|
//! Enabled by default.
|
||||||
//! - `multipart`: Enables parsing `multipart/form-data` requests with [`extract::Multipart`].
|
//! - `multipart`: Enables parsing `multipart/form-data` requests with [`extract::Multipart`].
|
||||||
//! - `tower-log`: Enables `tower`'s `log` feature. Enabled by default.
|
//! - `tower-log`: Enables `tower`'s `log` feature. Enabled by default.
|
||||||
//! - `ws`: Enables WebSockets support via [`extract::ws`].
|
//! - `ws`: Enables WebSockets support via [`extract::ws`].
|
||||||
@@ -1193,6 +1196,7 @@ pub(crate) mod macros;
|
|||||||
|
|
||||||
mod clone_box_service;
|
mod clone_box_service;
|
||||||
mod error;
|
mod error;
|
||||||
|
#[cfg(feature = "json")]
|
||||||
mod json;
|
mod json;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
@@ -1216,7 +1220,10 @@ pub use hyper::Server;
|
|||||||
pub use tower_http::add_extension::{AddExtension, AddExtensionLayer};
|
pub use tower_http::add_extension::{AddExtension, AddExtensionLayer};
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::{error::Error, json::Json, routing::Router};
|
#[cfg(feature = "json")]
|
||||||
|
pub use self::json::Json;
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use self::{error::Error, routing::Router};
|
||||||
|
|
||||||
/// Alias for a type-erased error type.
|
/// Alias for a type-erased error type.
|
||||||
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
|
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ mod redirect;
|
|||||||
pub mod sse;
|
pub mod sse;
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
|
#[cfg(feature = "json")]
|
||||||
pub use crate::Json;
|
pub use crate::Json;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
|
|||||||
+5
-2
@@ -37,7 +37,6 @@ use futures_util::{
|
|||||||
use http::Response;
|
use http::Response;
|
||||||
use http_body::Body as HttpBody;
|
use http_body::Body as HttpBody;
|
||||||
use pin_project_lite::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
use serde::Serialize;
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
fmt,
|
fmt,
|
||||||
@@ -181,6 +180,7 @@ pub struct Event {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum DataType {
|
enum DataType {
|
||||||
Text(String),
|
Text(String),
|
||||||
|
#[cfg(feature = "json")]
|
||||||
Json(String),
|
Json(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,9 +197,11 @@ impl Event {
|
|||||||
|
|
||||||
/// Set Server-sent event data
|
/// Set Server-sent event data
|
||||||
/// data field(s) ("data:<content>")
|
/// data field(s) ("data:<content>")
|
||||||
|
#[cfg(feature = "json")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||||
pub fn json_data<T>(mut self, data: T) -> Result<Event, serde_json::Error>
|
pub fn json_data<T>(mut self, data: T) -> Result<Event, serde_json::Error>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: serde::Serialize,
|
||||||
{
|
{
|
||||||
self.data = Some(DataType::Json(serde_json::to_string(&data)?));
|
self.data = Some(DataType::Json(serde_json::to_string(&data)?));
|
||||||
Ok(self)
|
Ok(self)
|
||||||
@@ -265,6 +267,7 @@ impl fmt::Display for Event {
|
|||||||
f.write_char('\n')?;
|
f.write_char('\n')?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "json")]
|
||||||
Some(DataType::Json(data)) => {
|
Some(DataType::Json(data)) => {
|
||||||
"data:".fmt(f)?;
|
"data:".fmt(f)?;
|
||||||
data.fmt(f)?;
|
data.fmt(f)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user