diff --git a/CHANGELOG.md b/CHANGELOG.md index 0623b4c39a..951b34edd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## :bug: Fixes +- **Studio Explorer Boilerplate HTML** ([PR #526](https://github.com/apollograpqhl/router/pull/526)) + + This replaces the behavior of redirecting directly to studio with the more complete implementation which includes a landing-page that is served locally and offers a redirect to Studio. This will match the behavior of Apollo Server and Apollo Gateway today, exactly. This offers more transparency to the user to understand what about to happen (the redirect) and allows them to optionally make the behavior sticky (on account of a browser cookie) for future requests. + - **Anonymous operation names are now empty in tracing** ([PR #525](https://github.com/apollograpqhl/router/pull/525)) When GraphQL operation names are not nececessary to execute an operation (i.e., when there is only a single operation in a GraphQL document) and the GraphQL operation is _not_ named (i.e., it is anonymous), the `operation_name` attribute on the trace spans that are associated with the request will no longer contain a single hyphen character (`-`) but will instead be an empty string. This matches the way that these operations are represented during the GraphQL operation's life-cycle as well. diff --git a/apollo-router-core/well_known_introspection_queries/homepage.graphql b/apollo-router-core/well_known_introspection_queries/homepage.graphql new file mode 100644 index 0000000000..b4685e218b --- /dev/null +++ b/apollo-router-core/well_known_introspection_queries/homepage.graphql @@ -0,0 +1 @@ +query { __typename } \ No newline at end of file diff --git a/apollo-router/resources/index.html b/apollo-router/resources/index.html new file mode 100644 index 0000000000..ee2a794df8 --- /dev/null +++ b/apollo-router/resources/index.html @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + Apollo Router + + + + +
+ +
+

Welcome to the Apollo Router

+

It appears that you might be offline. POST to this endpoint to query your graph:

+ +curl --request POST \\ + --header 'content-type: application/json' \\ + --url '' \\ + --data '{"query":"query { __typename }"}' +
+
+ + + + \ No newline at end of file diff --git a/apollo-router/src/warp_http_server_factory.rs b/apollo-router/src/warp_http_server_factory.rs index 3a2319819c..93ff9c024e 100644 --- a/apollo-router/src/warp_http_server_factory.rs +++ b/apollo-router/src/warp_http_server_factory.rs @@ -20,9 +20,8 @@ use tower_service::Service; use tracing::instrument::WithSubscriber; use tracing::{Level, Span}; use tracing_opentelemetry::OpenTelemetrySpanExt; -use warp::host::Authority; use warp::{ - http::{header::HeaderMap, StatusCode, Uri}, + http::{header::HeaderMap, StatusCode}, hyper::Body, Filter, }; @@ -246,7 +245,6 @@ where warp::get() .and(warp::path::end().or(warp::path("graphql")).unify()) .and(warp::header::optional::("accept")) - .and(warp::host::optional()) .and( warp::query::raw() .or(warp::any().map(String::default)) @@ -254,14 +252,11 @@ where ) .and(warp::header::headers_cloned()) .and_then( - move |accept: Option, - host: Option, - query: String, - header_map: HeaderMap| { + move |accept: Option, query: String, header_map: HeaderMap| { let service = service.clone(); async move { let reply: Box = if accept.map(prefers_html).unwrap_or_default() { - redirect_to_studio(host) + display_home_page() } else if let Ok(request) = graphql::Request::from_urlencoded_query(query) { run_graphql_request(service, http::Method::GET, request, header_map).await } else { @@ -277,29 +272,9 @@ where ) } -fn redirect_to_studio(host: Option) -> Box { - // Try to redirect to Studio - if host.is_some() { - if let Ok(uri) = format!( - "https://studio.apollographql.com/sandbox?endpoint=http://{}", - // we made sure host.is_some() above - host.unwrap() - ) - .parse::() - { - Box::new(warp::redirect::temporary(uri)) - } else { - Box::new(warp::reply::with_status( - "Invalid host to redirect to", - StatusCode::BAD_REQUEST, - )) - } - } else { - Box::new(warp::reply::with_status( - "Invalid host to redirect to", - StatusCode::BAD_REQUEST, - )) - } +fn display_home_page() -> Box { + let html = include_str!("../resources/index.html"); + Box::new(warp::reply::html(html)) } fn get_health_request() -> impl Filter,), Error = Rejection> + Clone { @@ -465,7 +440,7 @@ mod tests { use reqwest::header::{ ACCEPT, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, - LOCATION, ORIGIN, + ORIGIN, }; use reqwest::redirect::Policy; use reqwest::{Client, Method, StatusCode}; @@ -608,7 +583,7 @@ mod tests { } #[test(tokio::test)] - async fn redirect_to_studio() -> Result<(), FederatedServerError> { + async fn display_home_page() -> Result<(), FederatedServerError> { let expectations = MockRouterService::new(); let (server, client) = init(expectations).await; @@ -625,19 +600,15 @@ mod tests { .unwrap(); assert_eq!( response.status(), - StatusCode::TEMPORARY_REDIRECT, + StatusCode::OK, "{}", response.text().await.unwrap() ); - assert_header!( - &response, - LOCATION, - vec![format!( - "https://studio.apollographql.com/sandbox?endpoint={}", - server.listen_address() - )], - "Incorrect redirect url" - ); + assert!(response + .text() + .await + .unwrap() + .starts_with("")) } server.shutdown().await