Javadoc updates and rename WebInterceptorExecution
This commit is contained in:
@@ -30,11 +30,18 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
*/
|
||||
public class WebFluxGraphQLHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
private final WebInterceptorExecution executionChain;
|
||||
private final WebInterceptorExecutionChain executionChain;
|
||||
|
||||
|
||||
/**
|
||||
* Create a handler that executes queries through the given {@link GraphQL}
|
||||
* and and invokes the given interceptors to customize input to and the
|
||||
* result from the execution of the query.
|
||||
* @param graphQL the GraphQL instance to use for query execution
|
||||
* @param interceptors 0 or more interceptors to customize input and output
|
||||
*/
|
||||
public WebFluxGraphQLHandler(GraphQL graphQL, List<WebInterceptor> interceptors) {
|
||||
this.executionChain = new WebInterceptorExecution(graphQL, interceptors);
|
||||
this.executionChain = new WebInterceptorExecutionChain(graphQL, interceptors);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,14 +24,16 @@ import graphql.ExecutionInput;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.server.ServerWebInputException;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Container for input from an HTTP request to a GraphQL endpoint, including
|
||||
* URI, headers, and other inputs extracted from the body of the request.
|
||||
* Container for the input of a GraphQL query over HTTP. The input includes the
|
||||
* {@link UriComponents URL} and the headers of the request, as well as the
|
||||
* query name, operation name, and variables from the request body.
|
||||
*/
|
||||
public class WebInput {
|
||||
|
||||
@@ -69,27 +71,51 @@ public class WebInput {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the URI of the HTTP request including
|
||||
* {@link UriComponents#getQueryParams() query parameters}.
|
||||
*/
|
||||
public UriComponents uri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the headers of the request.
|
||||
*/
|
||||
public HttpHeaders headers() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query name extracted from the request body. This is guaranteed
|
||||
* to be a non-empty string, or otherwise the request is rejected via
|
||||
* {@link ServerWebInputException} as a 400 error.
|
||||
*/
|
||||
public String query() {
|
||||
return this.query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query operation name extracted from the request body or
|
||||
* {@code null} if not provided.
|
||||
*/
|
||||
@Nullable
|
||||
public String operationName() {
|
||||
return this.operationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query variables that can be referenced via $syntax extracted
|
||||
* from the request body or a {@code null} if not provided.
|
||||
*/
|
||||
public Map<String, Object> variables() {
|
||||
return this.variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link ExecutionInput} initialized with the {@link #query()},
|
||||
* {@link #operationName()}, and {@link #variables()}.
|
||||
*/
|
||||
public ExecutionInput toExecutionInput() {
|
||||
return ExecutionInput.newExecutionInput()
|
||||
.query(query())
|
||||
@@ -98,4 +124,11 @@ public class WebInput {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WebInput [" + uri() + " " + headers() + ", query='" + query() + "'" +
|
||||
(operationName() != null ? ", operationName='" + operationName() + "'" : "") +
|
||||
(!CollectionUtils.isEmpty(variables()) ? ", variables=" + variables() : "") +
|
||||
"]";
|
||||
}
|
||||
}
|
||||
@@ -18,20 +18,32 @@ package org.springframework.graphql;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.GraphQL;
|
||||
import graphql.ExecutionResult;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Interceptor for GraphQL over HTTP requests that allows customization of the
|
||||
* {@link ExecutionInput} and the {@link graphql.ExecutionResult} of
|
||||
* {@link GraphQL} query execution.
|
||||
* Web interceptor for GraphQL queries over HTTP. The interceptor allows
|
||||
* customization of the {@link ExecutionInput} for the query as well as the
|
||||
* {@link ExecutionResult} of the query and is supported for both Spring MVC and
|
||||
* Spring WebFlux.
|
||||
*
|
||||
* <p>A list of interceptors may be provided to {@link WebMvcGraphQLHandler} or
|
||||
* to {@link WebFluxGraphQLHandler}. Interceptors are executed in that provided
|
||||
* order where each interceptor sees the {@code ExecutionInput} or the
|
||||
* {@code ExecutionResult} that was customized by the previous interceptor.
|
||||
*/
|
||||
public interface WebInterceptor {
|
||||
|
||||
/**
|
||||
* Intercept a GraphQL over HTTP request before the query is executed.
|
||||
*
|
||||
* @param executionInput the input to use, initialized from the {@code WebInput}
|
||||
* <p>{@code ExecutionInput} is initially populated with the input from the
|
||||
* request body via {@link WebInput#toExecutionInput()} where the
|
||||
* {@link WebInput#query() query} is guaranteed to be a non-empty String.
|
||||
* Interceptors are then executed in order to further customize the input
|
||||
* and or perform other actions or checks.
|
||||
*
|
||||
* @param executionInput the input to use, initialized from {@code WebInput}
|
||||
* @param webInput the input from the HTTP request
|
||||
* @return the same instance or a new one via {@link ExecutionInput#transform(Consumer)}
|
||||
*/
|
||||
@@ -42,6 +54,10 @@ public interface WebInterceptor {
|
||||
/**
|
||||
* Intercept a GraphQL over HTTP request after the query is executed.
|
||||
*
|
||||
* <p>{@code WebOutput} initially wraps the {@link ExecutionResult} returned
|
||||
* from the execution of the query. Interceptors are then executed in order
|
||||
* to further customize it and/or perform other actions.
|
||||
*
|
||||
* @param webOutput the execution result
|
||||
* @return the same instance or a new one via {@link WebOutput#transform(Consumer)}
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@ import graphql.ExecutionResult;
|
||||
import graphql.GraphQL;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -32,14 +33,15 @@ import org.springframework.util.CollectionUtils;
|
||||
* {@link ExecutionInput} and the {@link ExecutionResult} of {@link GraphQL}
|
||||
* query execution.
|
||||
*/
|
||||
class WebInterceptorExecution {
|
||||
class WebInterceptorExecutionChain {
|
||||
|
||||
private final GraphQL graphQL;
|
||||
|
||||
private final List<WebInterceptor> interceptors;
|
||||
|
||||
|
||||
WebInterceptorExecution(GraphQL graphQL, List<WebInterceptor> interceptors) {
|
||||
WebInterceptorExecutionChain(GraphQL graphQL, List<WebInterceptor> interceptors) {
|
||||
Assert.notNull(graphQL, "GraphQL is required");
|
||||
this.graphQL = graphQL;
|
||||
this.interceptors = (!CollectionUtils.isEmpty(interceptors) ?
|
||||
Collections.unmodifiableList(new ArrayList<>(interceptors)) : Collections.emptyList());
|
||||
@@ -37,11 +37,18 @@ import org.springframework.web.servlet.function.ServerResponse;
|
||||
*/
|
||||
public class WebMvcGraphQLHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
private final WebInterceptorExecution executionChain;
|
||||
private final WebInterceptorExecutionChain executionChain;
|
||||
|
||||
|
||||
/**
|
||||
* Create a handler that executes queries through the given {@link GraphQL}
|
||||
* and and invokes the given interceptors to customize input to and the
|
||||
* result from the execution of the query.
|
||||
* @param graphQL the GraphQL instance to use for query execution
|
||||
* @param interceptors 0 or more interceptors to customize input and output
|
||||
*/
|
||||
public WebMvcGraphQLHandler(GraphQL graphQL, List<WebInterceptor> interceptors) {
|
||||
this.executionChain = new WebInterceptorExecution(graphQL, interceptors);
|
||||
this.executionChain = new WebInterceptorExecutionChain(graphQL, interceptors);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ public class WebOutput implements ExecutionResult {
|
||||
private final ExecutionResult executionResult;
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance that wraps the given {@link ExecutionResult}.
|
||||
*/
|
||||
public WebOutput(ExecutionResult executionResult) {
|
||||
this.executionResult = executionResult;
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link WebInterceptorExecution}.
|
||||
* Unit tests for {@link WebInterceptorExecutionChain}.
|
||||
*/
|
||||
public class WebInterceptorExecutionTests {
|
||||
public class WebInterceptorExecutionChainTests {
|
||||
|
||||
@Test
|
||||
void testInterceptorInvocation() throws Exception {
|
||||
@@ -65,7 +65,7 @@ public class WebInterceptorExecutionTests {
|
||||
Map body = mapper.reader().readValue("{\"query\": \"" + query + "\"}", Map.class);
|
||||
WebInput webInput = new WebInput(URI.create("/graphql"), new HttpHeaders(), body);
|
||||
|
||||
WebOutput webOutput = new WebInterceptorExecution(createGraphQL(), interceptors)
|
||||
WebOutput webOutput = new WebInterceptorExecutionChain(createGraphQL(), interceptors)
|
||||
.execute(webInput).block();
|
||||
|
||||
assertEquals(":pre1:pre2:pre3:post3:post2:post1", sb.toString());
|
||||
Reference in New Issue
Block a user