Allow HTTP GET and WebSocket to use the same path

Closes gh-30
This commit is contained in:
Rossen Stoyanchev
2021-02-05 21:07:27 +00:00
parent 2ebbd464b8
commit 4e735f1ca8
4 changed files with 35 additions and 16 deletions

View File

@@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.stream.Collectors;
import graphql.GraphQL;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -41,6 +42,7 @@ import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
@@ -90,14 +92,21 @@ public class WebFluxGraphQLAutoConfiguration {
public HandlerMapping graphQLWebSocketEndpoint(
GraphQLWebSocketHandler handler, GraphQLProperties properties) {
String path = properties.getWebsocket().getPath();
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setUrlMap(Collections.singletonMap(path, handler));
mapping.setOrder(-1); // Ahead of annotated controllers
return mapping;
WebSocketHandlerMapping handlerMapping = new WebSocketHandlerMapping();
handlerMapping.setUrlMap(Collections.singletonMap(properties.getWebsocket().getPath(), handler));
handlerMapping.setOrder(-2); // Ahead of HTTP endpoint ("routerFunctionMapping" bean)
return handlerMapping;
}
}
private static class WebSocketHandlerMapping extends SimpleUrlHandlerMapping {
@Override
public Mono<Object> getHandlerInternal(ServerWebExchange exchange) {
return ("WebSocket".equalsIgnoreCase(exchange.getRequest().getHeaders().getUpgrade()) ?
super.getHandlerInternal(exchange) : Mono.empty());
}
}
}

View File

@@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.websocket.server.ServerContainer;
import graphql.GraphQL;
@@ -38,6 +39,7 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.graphql.WebInterceptor;
import org.springframework.graphql.webmvc.GraphQLHttpHandler;
import org.springframework.graphql.webmvc.GraphQLWebSocketHandler;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.HandlerMapping;
@@ -103,16 +105,24 @@ public class WebMvcGraphQLAutoConfiguration {
@Bean
public HandlerMapping graphQLWebSocketEndpoint(GraphQLWebSocketHandler handler, GraphQLProperties properties) {
WebSocketHttpRequestHandler httpRequestHandler =
new WebSocketHttpRequestHandler(handler, new DefaultHandshakeHandler());
String path = properties.getWebsocket().getPath();
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setUrlMap(Collections.singletonMap(path, httpRequestHandler));
mapping.setOrder(-1); // Ahead of annotated controllers
return mapping;
WebSocketHandlerMapping handlerMapping = new WebSocketHandlerMapping();
handlerMapping.setUrlMap(Collections.singletonMap(
properties.getWebsocket().getPath(),
new WebSocketHttpRequestHandler(handler, new DefaultHandshakeHandler())));
handlerMapping.setOrder(2); // Ahead of HTTP endpoint ("routerFunctionMapping" bean)
return handlerMapping;
}
}
private static class WebSocketHandlerMapping extends SimpleUrlHandlerMapping {
@Override
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
return ("WebSocket".equalsIgnoreCase(request.getHeader(HttpHeaders.UPGRADE)) ?
super.getHandlerInternal(request) : null);
}
}
}

View File

@@ -1,4 +1,4 @@
spring.graphql.websocket.path=/graphql/websocket
spring.graphql.websocket.path=/graphql
management.endpoints.web.exposure.include=health,metrics,info
logging.level.org.springframework.web=debug
logging.level.org.springframework.http=debug

View File

@@ -8,7 +8,7 @@
<body>
<script type="text/javascript">
const client = graphqlWs.createClient({
url: 'ws://localhost:8080/graphql/websocket',
url: 'ws://localhost:8080/graphql',
});
// query