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

Commit cc9b648

Browse files
committed
feat: move playground into main starter
1 parent 166f991 commit cc9b648

File tree

95 files changed

+268
-416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+268
-416
lines changed

example-webflux/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ apply plugin: "org.springframework.boot"
2121

2222
dependencies {
2323
implementation(project(":graphql-spring-boot-starter"))
24-
implementation(project(":voyager-spring-boot-starter"))
25-
implementation(project(":playground-spring-boot-starter"))
2624

2725
implementation("org.springframework.boot:spring-boot-starter-webflux:$LIB_SPRING_BOOT_VER")
2826
implementation("org.springframework.boot:spring-boot-starter-actuator:$LIB_SPRING_BOOT_VER")

graphql-spring-boot-autoconfigure/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ dependencies {
5555
testImplementation "org.springframework.boot:spring-boot-starter-web"
5656
testImplementation "org.springframework.boot:spring-boot-starter-actuator"
5757
testImplementation "org.springframework.boot:spring-boot-starter-webflux"
58+
testImplementation "org.springframework.boot:spring-boot-starter-security"
59+
testImplementation "org.springframework.security:spring-security-test"
5860
testImplementation "io.projectreactor:reactor-core"
5961
testImplementation "io.reactivex.rxjava2:rxjava"
62+
testImplementation "org.jsoup:jsoup:$LIB_JSOUP_VER"
6063
}
6164

6265
compileJava.dependsOn(processResources)
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
package graphql.kickstart.playground.boot;
1+
package graphql.kickstart.autoconfigure.editor.playground;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import graphql.kickstart.autoconfigure.editor.playground.properties.PlaygroundProperties;
45
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
56
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
67
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -9,17 +10,16 @@
910

1011
@Configuration
1112
@ConditionalOnWebApplication
12-
@EnableConfigurationProperties(PlaygroundPropertiesConfiguration.class)
13+
@EnableConfigurationProperties(PlaygroundProperties.class)
1314
public class PlaygroundAutoConfiguration {
1415

1516
@Bean
1617
@ConditionalOnProperty(
1718
value = "graphql.playground.enabled",
18-
havingValue = "true",
19-
matchIfMissing = true)
19+
havingValue = "true")
2020
public PlaygroundController playgroundController(
21-
final PlaygroundPropertiesConfiguration playgroundPropertiesConfiguration,
21+
final PlaygroundProperties playgroundProperties,
2222
final ObjectMapper objectMapper) {
23-
return new PlaygroundController(playgroundPropertiesConfiguration, objectMapper);
23+
return new PlaygroundController(playgroundProperties, objectMapper);
2424
}
2525
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package graphql.kickstart.autoconfigure.editor.playground;
2+
3+
import static java.util.Objects.nonNull;
4+
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import graphql.kickstart.autoconfigure.editor.playground.properties.PlaygroundProperties;
7+
import java.io.IOException;
8+
import java.nio.charset.Charset;
9+
import java.nio.file.Paths;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
import lombok.RequiredArgsConstructor;
13+
import org.apache.commons.text.StringSubstitutor;
14+
import org.springframework.core.io.ClassPathResource;
15+
import org.springframework.stereotype.Controller;
16+
import org.springframework.ui.Model;
17+
import org.springframework.util.StreamUtils;
18+
import org.springframework.web.bind.annotation.GetMapping;
19+
import org.springframework.web.bind.annotation.RequestAttribute;
20+
21+
@Controller
22+
@RequiredArgsConstructor
23+
public class PlaygroundController {
24+
25+
private static final String CDN_ROOT = "https://cdn.jsdelivr.net/npm/graphql-playground-react";
26+
private static final String CSS_PATH = "static/css/index.css";
27+
private static final String FAVICON_PATH = "favicon.png";
28+
private static final String SCRIPT_PATH = "static/js/middleware.js";
29+
private static final String LOGO_PATH = "logo.png";
30+
31+
private static final String CSS_URL_ATTRIBUTE_NAME = "cssUrl";
32+
private static final String FAVICON_URL_ATTRIBUTE_NAME = "faviconUrl";
33+
private static final String SCRIPT_URL_ATTRIBUTE_NAME = "scriptUrl";
34+
private static final String LOGO_URL_ATTRIBUTE_NAME = "logoUrl";
35+
private static final String CSRF = "_csrf";
36+
37+
private final PlaygroundProperties properties;
38+
39+
private final ObjectMapper objectMapper;
40+
41+
@GetMapping("${graphql.playground.mapping:/playground}")
42+
public String playground(
43+
final Model model, final @RequestAttribute(value = CSRF, required = false) Object csrf)
44+
throws IOException {
45+
String template =
46+
StreamUtils.copyToString(
47+
new ClassPathResource("templates/playground.html").getInputStream(), Charset.defaultCharset());
48+
Map<String, String> replacements = new HashMap<>();
49+
if (properties.getCdn().isEnabled()) {
50+
addCdnUrls(replacements);
51+
} else {
52+
addLocalAssetUrls(replacements);
53+
}
54+
replacements.put("pageTitle", properties.getPageTitle());
55+
replacements.put("properties", objectMapper.writeValueAsString(properties));
56+
if (nonNull(csrf)) {
57+
replacements.put(CSRF, objectMapper.writeValueAsString(csrf));
58+
} else {
59+
replacements.put(CSRF, null);
60+
}
61+
return StringSubstitutor.replace(template, replacements);
62+
}
63+
64+
private String getCdnUrl(final String assetPath) {
65+
return String.format(
66+
"%s@%s/build/%s",
67+
CDN_ROOT, properties.getCdn().getVersion(), assetPath);
68+
}
69+
70+
private String getLocalUrl(final String assetPath) {
71+
return Paths.get(properties.getStaticPath().getBase(), assetPath)
72+
.toString()
73+
.replace('\\', '/');
74+
}
75+
76+
private void addCdnUrls(final Map<String, String> replacements) {
77+
replacements.put(CSS_URL_ATTRIBUTE_NAME, getCdnUrl(CSS_PATH));
78+
replacements.put(FAVICON_URL_ATTRIBUTE_NAME, getCdnUrl(FAVICON_PATH));
79+
replacements.put(SCRIPT_URL_ATTRIBUTE_NAME, getCdnUrl(SCRIPT_PATH));
80+
replacements.put(LOGO_URL_ATTRIBUTE_NAME, getCdnUrl(LOGO_PATH));
81+
}
82+
83+
private void addLocalAssetUrls(final Map<String, String> replacements) {
84+
replacements.put(CSS_URL_ATTRIBUTE_NAME, getLocalUrl(CSS_PATH));
85+
replacements.put(FAVICON_URL_ATTRIBUTE_NAME, getLocalUrl(FAVICON_PATH));
86+
replacements.put(SCRIPT_URL_ATTRIBUTE_NAME, getLocalUrl(SCRIPT_PATH));
87+
replacements.put(LOGO_URL_ATTRIBUTE_NAME, getLocalUrl(LOGO_PATH));
88+
}
89+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
package graphql.kickstart.playground.boot;
1+
package graphql.kickstart.autoconfigure.editor.playground;
22

3-
import graphql.kickstart.playground.boot.properties.PlaygroundProperties;
3+
import graphql.kickstart.autoconfigure.editor.playground.properties.PlaygroundProperties;
44
import lombok.Data;
55
import org.springframework.boot.context.properties.ConfigurationProperties;
66
import org.springframework.boot.context.properties.NestedConfigurationProperty;
77
import org.springframework.validation.annotation.Validated;
88

99
@Data
10-
@ConfigurationProperties(prefix = "graphql")
10+
1111
@Validated
1212
public class PlaygroundPropertiesConfiguration {
1313

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package graphql.kickstart.autoconfigure.editor.playground;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
5+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.context.annotation.Import;
9+
import org.springframework.core.io.ClassPathResource;
10+
import org.springframework.web.reactive.config.WebFluxConfigurer;
11+
import org.springframework.web.reactive.function.server.RouterFunction;
12+
import org.springframework.web.reactive.function.server.RouterFunctions;
13+
import org.springframework.web.reactive.function.server.ServerResponse;
14+
15+
@Configuration
16+
@Import(PlaygroundWebFluxControllerAdvice.class)
17+
@ConditionalOnClass(WebFluxConfigurer.class)
18+
@ConditionalOnProperty(value = "graphql.playground.enabled", havingValue = "true")
19+
@RequiredArgsConstructor
20+
public class PlaygroundWebFluxAutoConfiguration implements WebFluxConfigurer {
21+
22+
@Bean
23+
public RouterFunction<ServerResponse> playgroundStaticFilesRouter() {
24+
return RouterFunctions.resources(
25+
"/vendor/playground/**", new ClassPathResource("static/vendor/playground/"));
26+
}
27+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package graphql.kickstart.playground.boot;
1+
package graphql.kickstart.autoconfigure.editor.playground;
22

33
import lombok.NoArgsConstructor;
44
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package graphql.kickstart.playground.boot;
1+
package graphql.kickstart.autoconfigure.editor.playground;
22

33
import com.fasterxml.jackson.core.JsonGenerator;
44
import com.fasterxml.jackson.databind.JsonSerializer;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package graphql.kickstart.playground.boot.properties;
1+
package graphql.kickstart.autoconfigure.editor.playground.properties;
22

33
import javax.validation.constraints.NotBlank;
44
import lombok.Data;
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package graphql.kickstart.playground.boot.properties;
1+
package graphql.kickstart.autoconfigure.editor.playground.properties;
22

33
import com.fasterxml.jackson.annotation.JsonIgnore;
44
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -7,10 +7,14 @@
77
import java.util.Map;
88
import javax.validation.constraints.NotBlank;
99
import lombok.Data;
10+
import org.springframework.boot.context.properties.ConfigurationProperties;
1011
import org.springframework.boot.context.properties.NestedConfigurationProperty;
12+
import org.springframework.validation.annotation.Validated;
1113

1214
@Data
15+
@Validated
1316
@JsonInclude(JsonInclude.Include.NON_EMPTY)
17+
@ConfigurationProperties(prefix = "graphql.playground")
1418
public class PlaygroundProperties {
1519

1620
@NotBlank private String endpoint = "/graphql";

0 commit comments

Comments
 (0)