Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit d157349

Browse files
author
Ronny Bräunlich
committed
Make GraphiQLController an abstract class with two subclasses, one for servlet and one for reactive. Adjust the autoconfiguration accordingly.
1 parent 4c7cdba commit d157349

File tree

5 files changed

+124
-20
lines changed

5 files changed

+124
-20
lines changed

graphiql-spring-boot-autoconfigure/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dependencies{
2323
compile "org.apache.commons:commons-text:1.1"
2424
compileOnly "org.springframework.boot:spring-boot-starter-web:$LIB_SPRING_BOOT_VER"
2525
compileOnly "org.springframework.boot:spring-boot-starter-security:$LIB_SPRING_BOOT_VER"
26+
compileOnly "io.projectreactor:reactor-core:3.3.0.RELEASE"
2627

2728
testCompile "org.springframework.boot:spring-boot-starter-web:$LIB_SPRING_BOOT_VER"
2829
testCompile "org.springframework.boot:spring-boot-starter-test:$LIB_SPRING_BOOT_VER"
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,36 @@
11
package com.oembedler.moon.graphiql.boot;
22

33
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
45
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
56
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
67
import org.springframework.boot.context.properties.EnableConfigurationProperties;
78
import org.springframework.context.annotation.Bean;
89
import org.springframework.context.annotation.Configuration;
910
import org.springframework.web.servlet.DispatcherServlet;
1011

12+
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET;
13+
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;
14+
1115
/**
1216
* @author Andrew Potter
17+
* @author Ronny Bräunlich
1318
*/
1419
@Configuration
15-
@ConditionalOnWebApplication
16-
@ConditionalOnClass(DispatcherServlet.class)
20+
@ConditionalOnProperty(value = "graphiql.enabled", havingValue = "true", matchIfMissing = true)
1721
@EnableConfigurationProperties(GraphiQLProperties.class)
1822
public class GraphiQLAutoConfiguration {
1923

20-
@Bean
21-
@ConditionalOnProperty(value = "graphiql.enabled", havingValue = "true", matchIfMissing = true)
22-
GraphiQLController graphiQLController() {
23-
return new GraphiQLController();
24+
@Bean(name = "graphiQLController")
25+
@ConditionalOnWebApplication(type=SERVLET)
26+
ServletGraphiQLController servletGraphiQLController() {
27+
return new ServletGraphiQLController();
2428
}
2529

30+
@Bean(name = "graphiQLController")
31+
@ConditionalOnMissingBean(ServletGraphiQLController.class)
32+
@ConditionalOnWebApplication(type=REACTIVE)
33+
ReactiveGraphiQLController reactiveGraphiQLController() {
34+
return new ReactiveGraphiQLController();
35+
}
2636
}

graphiql-spring-boot-autoconfigure/src/main/java/com/oembedler/moon/graphiql/boot/GraphiQLController.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
* @author Andrew Potter
3131
*/
3232
@Slf4j
33-
@Controller
34-
public class GraphiQLController {
33+
public abstract class GraphiQLController {
3534

3635
private static final String CDNJS_CLOUDFLARE_COM_AJAX_LIBS = "//cdnjs.cloudflare.com/ajax/libs/";
3736
private static final String CDN_JSDELIVR_NET_NPM = "//cdn.jsdelivr.net/npm/";
@@ -48,7 +47,6 @@ public class GraphiQLController {
4847
private String props;
4948
private Properties headerProperties;
5049

51-
@PostConstruct
5250
public void onceConstructed() throws IOException {
5351
loadTemplate();
5452
loadProps();
@@ -78,23 +76,20 @@ private void addIfAbsent(Properties headerProperties, String header) {
7876
}
7977
}
8078

81-
@GetMapping(value = "${graphiql.mapping:/graphiql}")
82-
public void graphiql(HttpServletRequest request, HttpServletResponse response, @PathVariable Map<String, String> params) throws IOException {
83-
response.setContentType("text/html; charset=UTF-8");
84-
Object csrf = request.getAttribute("_csrf");
79+
public byte[] graphiql(String contextPath, @PathVariable Map<String, String> params, Object csrf) {
8580
if (csrf != null) {
8681
CsrfToken csrfToken = (CsrfToken) csrf;
8782
headerProperties.setProperty(csrfToken.getHeaderName(), csrfToken.getToken());
8883
}
8984

9085
Map<String, String> replacements = getReplacements(
91-
constructGraphQlEndpoint(request, params),
92-
request.getContextPath() + graphiQLProperties.getEndpoint().getSubscriptions(),
93-
request.getContextPath() + graphiQLProperties.getSTATIC().getBasePath()
86+
constructGraphQlEndpoint(contextPath, params),
87+
contextPath + graphiQLProperties.getEndpoint().getSubscriptions(),
88+
contextPath + graphiQLProperties.getSTATIC().getBasePath()
9489
);
9590

9691
String populatedTemplate = StrSubstitutor.replace(template, replacements);
97-
response.getOutputStream().write(populatedTemplate.getBytes(Charset.defaultCharset()));
92+
return populatedTemplate.getBytes(Charset.defaultCharset());
9893
}
9994

10095
private Map<String, String> getReplacements(
@@ -169,13 +164,13 @@ private String joinJsDelivrPath(String library, String cdnVersion, String cdnFil
169164
return CDN_JSDELIVR_NET_NPM + library + "@" + cdnVersion + "/" + cdnFileName;
170165
}
171166

172-
private String constructGraphQlEndpoint(HttpServletRequest request, @RequestParam Map<String, String> params) {
167+
private String constructGraphQlEndpoint(String contextPath, @RequestParam Map<String, String> params) {
173168
String endpoint = graphiQLProperties.getEndpoint().getGraphql();
174169
for (Map.Entry<String, String> param : params.entrySet()) {
175170
endpoint = endpoint.replaceAll("\\{" + param.getKey() + "}", param.getValue());
176171
}
177-
if (StringUtils.isNotBlank(request.getContextPath()) && !endpoint.startsWith(request.getContextPath())) {
178-
return request.getContextPath() + endpoint;
172+
if (StringUtils.isNotBlank(contextPath) && !endpoint.startsWith(contextPath)) {
173+
return contextPath + endpoint;
179174
}
180175
return endpoint;
181176
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.oembedler.moon.graphiql.boot;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.apache.commons.lang3.StringUtils;
5+
import org.apache.commons.lang3.text.StrSubstitutor;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.core.io.ClassPathResource;
8+
import org.springframework.core.io.buffer.DataBufferFactory;
9+
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
10+
import org.springframework.http.MediaType;
11+
import org.springframework.http.server.reactive.ServerHttpRequest;
12+
import org.springframework.http.server.reactive.ServerHttpResponse;
13+
import org.springframework.stereotype.Controller;
14+
import org.springframework.util.StreamUtils;
15+
import org.springframework.web.bind.annotation.PathVariable;
16+
import org.springframework.web.bind.annotation.RequestMapping;
17+
import org.springframework.web.bind.annotation.RequestParam;
18+
import reactor.core.publisher.Mono;
19+
20+
import javax.annotation.PostConstruct;
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.nio.charset.Charset;
24+
import java.util.HashMap;
25+
import java.util.Map;
26+
27+
@Slf4j
28+
@Controller
29+
public class ReactiveGraphiQLController extends GraphiQLController {
30+
31+
private DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
32+
33+
@PostConstruct
34+
public void onceConstructed() throws IOException {
35+
super.onceConstructed();
36+
}
37+
38+
@RequestMapping(value = "${graphiql.mapping:/api}")
39+
public Mono<Void> graphiql(ServerHttpRequest request, ServerHttpResponse response,
40+
@PathVariable Map<String, String> params) {
41+
response.getHeaders().setContentType(MediaType.TEXT_HTML);
42+
Object csrf = request.getQueryParams().getFirst("_csrf");
43+
return response.writeWith(Mono.just(request.getPath().contextPath().value())
44+
.map(contextPath -> super.graphiql(contextPath, params, csrf))
45+
.map(dataBufferFactory::wrap));
46+
}
47+
48+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.oembedler.moon.graphiql.boot;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.apache.commons.lang3.StringUtils;
7+
import org.apache.commons.lang3.text.StrSubstitutor;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.core.env.Environment;
10+
import org.springframework.core.io.ClassPathResource;
11+
import org.springframework.http.MediaType;
12+
import org.springframework.security.web.csrf.CsrfToken;
13+
import org.springframework.stereotype.Controller;
14+
import org.springframework.util.StreamUtils;
15+
import org.springframework.web.bind.annotation.GetMapping;
16+
import org.springframework.web.bind.annotation.PathVariable;
17+
import org.springframework.web.bind.annotation.RequestParam;
18+
19+
import javax.annotation.PostConstruct;
20+
import javax.servlet.http.HttpServletRequest;
21+
import javax.servlet.http.HttpServletResponse;
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.nio.charset.Charset;
25+
import java.util.HashMap;
26+
import java.util.Map;
27+
import java.util.Properties;
28+
29+
/**
30+
* @author Andrew Potter
31+
*/
32+
@Slf4j
33+
@Controller
34+
public class ServletGraphiQLController extends GraphiQLController{
35+
36+
@PostConstruct
37+
public void onceConstructed() throws IOException {
38+
super.onceConstructed();
39+
}
40+
41+
@GetMapping(value = "${graphiql.mapping:/graphiql}")
42+
public void graphiql(HttpServletRequest request, HttpServletResponse response,
43+
@PathVariable Map<String, String> params) throws IOException {
44+
response.setContentType("text/html; charset=UTF-8");
45+
Object csrf = request.getAttribute("_csrf");
46+
byte[] graphiqlBytes = super.graphiql(request.getContextPath(), params, csrf);
47+
response.getOutputStream().write(graphiqlBytes);
48+
}
49+
50+
}

0 commit comments

Comments
 (0)