Skip to content

Commit

Permalink
Support for response headers through WebOutput
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoyanchev committed Oct 7, 2020
1 parent d4b9c47 commit 7eafec2
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@ public Mono<ServerResponse> handle(ServerRequest request) {
WebInput webInput = new WebInput(request.uri(), request.headers().asHttpHeaders(), body);
return this.executionChain.execute(webInput);
})
.flatMap(output -> ServerResponse.ok().bodyValue(output.toSpecification()));
.flatMap(output -> {
ServerResponse.BodyBuilder builder = ServerResponse.ok();
if (output.getHeaders() != null) {
builder.headers(headers -> headers.putAll(output.getHeaders()));
}
return builder.bodyValue(output.toSpecification());
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private Mono<ExecutionInput> createInputChain(WebInput webInput) {
}

private Mono<WebOutput> createOutputChain(Mono<ExecutionResult> resultMono) {
Mono<WebOutput> outputMono = resultMono.map(WebOutput::new);
Mono<WebOutput> outputMono = resultMono.map((ExecutionResult executionResult) -> new WebOutput(executionResult, null));
for (int i = this.interceptors.size() - 1 ; i >= 0; i--) {
WebInterceptor interceptor = this.interceptors.get(i);
outputMono = outputMono.flatMap(interceptor::postHandle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import javax.servlet.ServletException;

import graphql.ExecutionResult;
import graphql.GraphQL;
import reactor.core.publisher.Mono;

Expand Down Expand Up @@ -60,8 +59,15 @@ public WebMvcGraphQLHandler(GraphQL graphQL, List<WebInterceptor> interceptors)
*/
public ServerResponse handle(ServerRequest request) throws ServletException {
WebInput webInput = new WebInput(request.uri(), request.headers().asHttpHeaders(), readBody(request));
Mono<WebOutput> outputMono = this.executionChain.execute(webInput);
return ServerResponse.ok().body(outputMono.map(ExecutionResult::toSpecification));
Mono<ServerResponse> responseMono = this.executionChain.execute(webInput)
.map(output -> {
ServerResponse.BodyBuilder builder = ServerResponse.ok();
if (output.getHeaders() != null) {
builder.headers(headers -> headers.putAll(output.getHeaders()));
}
return builder.body(output.toSpecification());
});
return ServerResponse.async(responseMono);
}

private static Map<String, Object> readBody(ServerRequest request) throws ServletException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import graphql.ExecutionResultImpl;
import graphql.GraphQLError;

import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;


Expand All @@ -35,12 +36,16 @@ public class WebOutput implements ExecutionResult {

private final ExecutionResult executionResult;

@Nullable
private final HttpHeaders headers;


/**
* Create an instance that wraps the given {@link ExecutionResult}.
*/
public WebOutput(ExecutionResult executionResult) {
public WebOutput(ExecutionResult executionResult, @Nullable HttpHeaders headers) {
this.executionResult = executionResult;
this.headers = headers;
}


Expand Down Expand Up @@ -69,6 +74,14 @@ public Map<String, Object> toSpecification() {
return this.executionResult.toSpecification();
}

/**
* Return headers to be added to the HTTP response.
*/
@Nullable
public HttpHeaders getHeaders() {
return this.headers;
}

/**
* Transform this {@code WebOutput} instance through a {@link Builder} and
* return a new instance with the modified values.
Expand All @@ -90,12 +103,18 @@ public static class Builder {
@Nullable
private Map<Object, Object> extensions;

@Nullable
private HttpHeaders headers;


public Builder(WebOutput output) {
this.data = output.getData();
this.errors = output.getErrors();
this.extensions = output.getExtensions();
this.headers = output.getHeaders();
}


/**
* Set the execution {@link ExecutionResult#getData() data}.
*/
Expand All @@ -120,8 +139,26 @@ public Builder extensions(@Nullable Map<Object, Object> extensions) {
return this;
}

public Builder header(String name, String... values) {
initHeaders();
for (String value : values) {
this.headers.add(name, value);
}
return this;
}

public Builder headers(Consumer<HttpHeaders> consumer) {
initHeaders();
consumer.accept(this.headers);
return this;
}

private void initHeaders() {
this.headers = (this.headers != null ? this.headers : new HttpHeaders());
}

public WebOutput build() {
return new WebOutput(new ExecutionResultImpl(this.data, this.errors, this.extensions));
return new WebOutput(new ExecutionResultImpl(this.data, this.errors, this.extensions), this.headers);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ void testInterceptorInvocation() throws Exception {

assertThat(sb.toString()).isEqualTo(":pre1:pre2:pre3:post3:post2:post1");
assertThat(webOutput.isDataPresent()).isTrue();
assertThat(webOutput.getHeaders().get("MyHeader")).containsExactly("MyValue3", "MyValue2", "MyValue1");
}


private static GraphQL createGraphQL() throws Exception {
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type(newTypeWiring("Query").dataFetcher("bookById", GraphQLDataFetchers.getBookByIdDataFetcher()))
Expand Down Expand Up @@ -105,7 +107,10 @@ public Mono<ExecutionInput> preHandle(ExecutionInput executionInput, WebInput we
@Override
public Mono<WebOutput> postHandle(WebOutput webOutput) {
this.output.append(":post").append(this.index);
return Mono.delay(Duration.ofMillis(50)).map(aLong -> webOutput);
return Mono.delay(Duration.ofMillis(50))
.map(aLong -> webOutput.transform(builder -> {
builder.header("myHeader", "MyValue" + this.index);
}));
}
}

Expand Down

0 comments on commit 7eafec2

Please sign in to comment.