diff --git a/src/http/graphiql_v2_source.rs b/src/http/graphiql_v2_source.rs new file mode 100644 index 00000000..3f4cb8b3 --- /dev/null +++ b/src/http/graphiql_v2_source.rs @@ -0,0 +1,341 @@ +use std::collections::HashMap; + +/// A builder for constructing a GraphiQL (v2) HTML page. +/// +/// # Example +/// +/// ```rust +/// use async_graphql::http::*; +/// +/// GraphiQLSource::build() +/// .endpoint("http://localhost:8000") +/// .subscription_endpoint("ws://localhost:8000/ws") +/// .header("Authorization", "Bearer ") +/// .finish(); +/// ``` +#[derive(Default)] +pub struct GraphiQLSource<'a> { + endpoint: &'a str, + subscription_endpoint: Option<&'a str>, + headers: Option>, +} + +impl<'a> GraphiQLSource<'a> { + /// Creates a builder for constructing a GraphiQL (v2) HTML page. + pub fn build() -> GraphiQLSource<'a> { + Default::default() + } + + /// Sets the endpoint of the server GraphiQL will connect to. + #[must_use] + pub fn endpoint(self, endpoint: &'a str) -> GraphiQLSource<'a> { + GraphiQLSource { endpoint, ..self } + } + + /// Sets the subscription endpoint of the server GraphiQL will connect to. + pub fn subscription_endpoint(self, endpoint: &'a str) -> GraphiQLSource<'a> { + GraphiQLSource { + subscription_endpoint: Some(endpoint), + ..self + } + } + + /// Sets a header to be sent with requests GraphiQL will send. + pub fn header(self, name: &'a str, value: &'a str) -> GraphiQLSource<'a> { + let mut headers = match self.headers { + Some(headers) => headers, + None => HashMap::new(), + }; + headers.insert(name, value); + GraphiQLSource { + headers: Some(headers), + ..self + } + } + + /// Returns a GraphiQL (v2) HTML page. + pub fn finish(self) -> String { + let graphiql_url = format!("'{}'", self.endpoint); + let graphiql_subscription_url = self + .subscription_endpoint + .map(|endpoint| format!("'{}'", endpoint)) + .unwrap_or_else(|| "undefined".into()); + let graphiql_headers = match self.headers { + Some(headers) => serde_json::to_string(&headers).unwrap(), + None => "undefined".into(), + }; + + r#" + + + + + + + + + GraphiQL IDE + + + + + + + + + +
Loading...
+ + + + +"# + .replace("%GRAPHIQL_URL%", &graphiql_url) + .replace("%GRAPHIQL_SUBSCRIPTION_URL%", &graphiql_subscription_url) + .replace("%GRAPHIQL_HEADERS%", &graphiql_headers) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_with_only_url() { + let graphiql_source = GraphiQLSource::build() + .endpoint("http://localhost:8000") + .finish(); + + assert_eq!( + graphiql_source, + r#" + + + + + + + + + GraphiQL IDE + + + + + + + + + +
Loading...
+ + + + +"# + ) + } + + #[test] + fn test_with_both_urls() { + let graphiql_source = GraphiQLSource::build() + .endpoint("http://localhost:8000") + .subscription_endpoint("ws://localhost:8000/ws") + .finish(); + + assert_eq!( + graphiql_source, + r#" + + + + + + + + + GraphiQL IDE + + + + + + + + + +
Loading...
+ + + + +"# + ) + } + + #[test] + fn test_with_all_options() { + let graphiql_source = GraphiQLSource::build() + .endpoint("http://localhost:8000") + .subscription_endpoint("ws://localhost:8000/ws") + .header("Authorization", "Bearer ") + .finish(); + + assert_eq!( + graphiql_source, + r#" + + + + + + + + + GraphiQL IDE + + + + + + + + + +
Loading...
+ + + + +"# + ) + } +} diff --git a/src/http/mod.rs b/src/http/mod.rs index 3b1c5b3c..c4ddfce0 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -1,12 +1,14 @@ //! A helper module that supports HTTP mod graphiql_source; +mod graphiql_v2_source; mod multipart; mod playground_source; mod websocket; use futures_util::io::{AsyncRead, AsyncReadExt}; pub use graphiql_source::graphiql_source; +pub use graphiql_v2_source::GraphiQLSource; use mime; pub use multipart::MultipartOptions; pub use playground_source::{playground_source, GraphQLPlaygroundConfig};