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

Commit efcd618

Browse files
committed
fix(#529): refactor altair resources
1 parent 401a3d9 commit efcd618

File tree

7 files changed

+90
-119
lines changed

7 files changed

+90
-119
lines changed

README.md

+38-38
Original file line numberDiff line numberDiff line change
@@ -109,22 +109,22 @@ repositories {
109109
}
110110
111111
dependencies {
112-
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:11.0.0'
112+
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:12.0.0'
113113
114114
// to embed Altair tool
115-
runtimeOnly 'com.graphql-java-kickstart:altair-spring-boot-starter:11.0.0'
115+
runtimeOnly 'com.graphql-java-kickstart:altair-spring-boot-starter:12.0.0'
116116
117117
// to embed GraphiQL tool
118-
runtimeOnly 'com.graphql-java-kickstart:graphiql-spring-boot-starter:11.0.0'
118+
runtimeOnly 'com.graphql-java-kickstart:graphiql-spring-boot-starter:12.0.0'
119119
120120
// to embed GraphQL Playground tool
121-
runtimeOnly 'com.graphql-java-kickstart:playground-spring-boot-starter:11.0.0'
121+
runtimeOnly 'com.graphql-java-kickstart:playground-spring-boot-starter:12.0.0'
122122
123123
// to embed Voyager tool
124-
runtimeOnly 'com.graphql-java-kickstart:voyager-spring-boot-starter:11.0.0'
124+
runtimeOnly 'com.graphql-java-kickstart:voyager-spring-boot-starter:12.0.0'
125125
126126
// testing facilities
127-
testImplementation 'com.graphql-java-kickstart:graphql-spring-boot-starter-test:11.0.0'
127+
testImplementation 'com.graphql-java-kickstart:graphql-spring-boot-starter-test:12.0.0'
128128
}
129129
```
130130

@@ -134,46 +134,46 @@ Maven:
134134
<dependency>
135135
<groupId>com.graphql-java-kickstart</groupId>
136136
<artifactId>graphql-spring-boot-starter</artifactId>
137-
<version>11.0.0</version>
137+
<version>12.0.0</version>
138138
</dependency>
139139

140140
<!-- to embed Altair tool -->
141141
<dependency>
142142
<groupId>com.graphql-java-kickstart</groupId>
143143
<artifactId>altair-spring-boot-starter</artifactId>
144-
<version>11.0.0</version>
144+
<version>12.0.0</version>
145145
<scope>runtime</scope>
146146
</dependency>
147147

148148
<!-- to embed GraphiQL tool -->
149149
<dependency>
150150
<groupId>com.graphql-java-kickstart</groupId>
151151
<artifactId>graphiql-spring-boot-starter</artifactId>
152-
<version>11.0.0</version>
152+
<version>12.0.0</version>
153153
<scope>runtime</scope>
154154
</dependency>
155155

156156
<!-- to embed GraphQL Playground tool -->
157157
<dependency>
158158
<groupId>com.graphql-java-kickstart</groupId>
159159
<artifactId>playground-spring-boot-starter</artifactId>
160-
<version>11.0.0</version>
160+
<version>12.0.0</version>
161161
<scope>runtime</scope>
162162
</dependency>
163163

164164
<!-- to embed Voyager tool -->
165165
<dependency>
166166
<groupId>com.graphql-java-kickstart</groupId>
167167
<artifactId>voyager-spring-boot-starter</artifactId>
168-
<version>11.0.0</version>
168+
<version>12.0.0</version>
169169
<scope>runtime</scope>
170170
</dependency>
171171

172172
<!-- testing facilities -->
173173
<dependency>
174174
<groupId>com.graphql-java-kickstart</groupId>
175175
<artifactId>graphql-spring-boot-starter-test</artifactId>
176-
<version>11.0.0</version>
176+
<version>12.0.0</version>
177177
<scope>test</scope>
178178
</dependency>
179179

@@ -298,37 +298,37 @@ or `application.properties`):
298298

299299
```yaml
300300
altair:
301-
mapping: /altair
302-
endpoint:
303-
graphql: /graphql
304-
subscriptions: /subscriptions
305-
subscriptions:
306-
timeout: 30
307-
reconnect: false
308-
static:
309-
basePath: /
310-
enabled: true
311-
pageTitle: Altair
312-
cdn:
313-
enabled: false
314-
version: 4.0.2
315-
options:
316-
initial-settings:
317-
theme: dracula
318-
props:
319-
resources:
320-
defaultQuery: defaultQuery.graphql
321-
variables: variables.graphql
322-
headers:
323-
Authorization: "Bearer <your-token>"
301+
enabled: true
302+
mapping: /altair
303+
subscriptions:
304+
timeout: 30
305+
reconnect: false
306+
static:
307+
base-path: /
308+
page-title: Altair
309+
cdn:
310+
enabled: false
311+
version: 4.0.2
312+
options:
313+
endpoint-url: /graphql
314+
subscriptions-endpoint: /subscriptions
315+
initial-settings:
316+
theme: dracula
317+
initial-headers:
318+
Authorization: "Bearer <your-token>"
319+
resources:
320+
initial-query: defaultQuery.graphql
321+
initial-variables: variables.graphql
322+
initial-pre-request-script: pre-request.graphql
323+
initial-post-request-script: post-request.graphql
324324
```
325325

326326
By default Altair is served from within the package. This can be configured to be served from CDN
327-
instead, by setting the property `altair.cdn.enabled` to `true`.
327+
instead, by setting the property `graphql.altair.cdn.enabled` to `true`.
328328

329-
You are able to set the Altair options as well using the `altair.options` group. Since setting (
329+
You are able to set the Altair options as well using the `graphql.altair.options` group. Since setting (
330330
large) queries in the properties like this isn't very readable, you can use the properties in
331-
the `altair.props.resources` group to set the classpath resources that should be loaded.
331+
the `graphql.altair.resources` group to set the classpath resources that should be loaded.
332332

333333
# Enable GraphQL Playground
334334

example/src/main/resources/application.yml

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ graphql:
3232
theme: dracula
3333
endpoint-url: /graphql
3434

35-
3635
graphiql:
3736
enabled: true
3837
cdn:

graphql-spring-boot-autoconfigure/src/main/java/graphql/kickstart/autoconfigure/editor/altair/AltairAutoConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
/** @author Moncef AOUDIA */
1212
@Configuration
1313
@ConditionalOnWebApplication
14-
@EnableConfigurationProperties({AltairProperties.class, AltairOptions.class})
14+
@EnableConfigurationProperties({AltairProperties.class, AltairOptions.class, AltairResources.class})
1515
@ConditionalOnClass(DispatcherServlet.class)
1616
public class AltairAutoConfiguration {
1717

graphql-spring-boot-autoconfigure/src/main/java/graphql/kickstart/autoconfigure/editor/altair/AltairController.java

+11-61
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,24 @@
55
import static org.apache.commons.lang3.StringUtils.isNumeric;
66

77
import com.fasterxml.jackson.annotation.JsonInclude.Include;
8-
import com.fasterxml.jackson.core.JsonProcessingException;
98
import com.fasterxml.jackson.databind.ObjectMapper;
10-
import graphql.kickstart.autoconfigure.editor.PropertyGroupReader;
11-
import graphql.kickstart.autoconfigure.editor.PropsLoader;
129
import java.io.IOException;
1310
import java.io.InputStream;
1411
import java.nio.charset.Charset;
1512
import java.util.HashMap;
1613
import java.util.Map;
17-
import java.util.Properties;
1814
import javax.annotation.PostConstruct;
19-
import javax.servlet.http.HttpServletRequest;
2015
import javax.servlet.http.HttpServletResponse;
2116
import lombok.SneakyThrows;
2217
import lombok.extern.slf4j.Slf4j;
2318
import lombok.val;
2419
import org.apache.commons.lang3.StringUtils;
2520
import org.apache.commons.text.StringSubstitutor;
2621
import org.springframework.beans.factory.annotation.Autowired;
27-
import org.springframework.core.env.Environment;
2822
import org.springframework.core.io.ClassPathResource;
2923
import org.springframework.stereotype.Controller;
3024
import org.springframework.util.StreamUtils;
3125
import org.springframework.web.bind.annotation.GetMapping;
32-
import org.springframework.web.bind.annotation.PathVariable;
33-
import org.springframework.web.bind.annotation.RequestParam;
3426

3527
/** @author Moncef AOUDIA */
3628
@Slf4j
@@ -39,23 +31,18 @@ public class AltairController {
3931

4032
private static final String CDN_JSDELIVR_NET_NPM = "//cdn.jsdelivr.net/npm/";
4133
private static final String ALTAIR = "altair-static";
42-
34+
private final ObjectMapper objectMapper = new ObjectMapper();
4335
@Autowired private AltairProperties altairProperties;
4436
@Autowired private AltairOptions altairOptions;
45-
private final ObjectMapper objectMapper = new ObjectMapper();
46-
47-
@Autowired private Environment environment;
37+
@Autowired private AltairResources altairResources;
4838

4939
private String template;
50-
private String props;
51-
private String headers;
5240

5341
@PostConstruct
5442
public void onceConstructed() throws IOException {
5543
objectMapper.setSerializationInclusion(Include.NON_NULL);
44+
altairResources.load(altairOptions);
5645
loadTemplate();
57-
loadProps();
58-
loadHeaders();
5946
}
6047

6148
private void loadTemplate() throws IOException {
@@ -65,57 +52,33 @@ private void loadTemplate() throws IOException {
6552
}
6653
}
6754

68-
private void loadProps() throws IOException {
69-
props = new PropsLoader(environment, "graphql.altair.props.resources.", "graphql.altair.props.variables.").load();
70-
}
71-
72-
private void loadHeaders() throws JsonProcessingException {
73-
PropertyGroupReader propertyReader = new PropertyGroupReader(environment, "graphql.altair.headers.");
74-
Properties headerProperties = propertyReader.load();
75-
this.headers = new ObjectMapper().writeValueAsString(headerProperties);
76-
}
77-
7855
@GetMapping(value = "${graphql.altair.mapping:/altair}")
79-
public void altair(
80-
HttpServletRequest request,
81-
HttpServletResponse response,
82-
@PathVariable Map<String, String> params)
83-
throws IOException {
56+
public void altair(HttpServletResponse response) throws IOException {
8457
response.setContentType("text/html; charset=UTF-8");
85-
86-
Map<String, String> replacements =
87-
getReplacements(
88-
constructGraphQlEndpoint(request, params),
89-
request.getContextPath() + altairProperties.getEndpoint().getSubscriptions());
90-
91-
String populatedTemplate = StringSubstitutor.replace(template, replacements);
58+
String populatedTemplate = StringSubstitutor.replace(template, getReplacements());
9259
response.getOutputStream().write(populatedTemplate.getBytes(Charset.defaultCharset()));
9360
}
9461

9562
@SneakyThrows
96-
private Map<String, String> getReplacements(
97-
String graphqlEndpoint, String subscriptionsEndpoint) {
63+
private Map<String, String> getReplacements() {
9864
Map<String, String> replacements = new HashMap<>();
99-
replacements.put("graphqlEndpoint", graphqlEndpoint);
100-
replacements.put("subscriptionsEndpoint", subscriptionsEndpoint);
10165
replacements.put("pageTitle", altairProperties.getPageTitle());
10266
replacements.put("pageFavicon", getResourceUrl("favicon.ico", "favicon.ico"));
10367
replacements.put(
10468
"altairBaseUrl",
10569
getResourceUrl(
10670
StringUtils.join(altairProperties.getBasePath(), "/vendor/altair/"),
107-
joinJsUnpkgPath(ALTAIR, altairProperties.getCdn().getVersion(), "build/dist/")));
71+
joinJsdelivrPath(altairProperties.getCdn().getVersion())));
10872
replacements.put(
10973
"altairLogoUrl", getResourceUrl("assets/img/logo_350.svg", "assets/img/logo_350.svg"));
11074
replacements.put("altairCssUrl", getResourceUrl("styles.css", "styles.css"));
11175

11276
val suffix = isJsSuffixAdded() ? "-es2018.js" : ".js";
11377
replacements.put("altairMainJsUrl", getResourceUrl("main-es2018.js", "main" + suffix));
114-
replacements.put("altairPolyfillsJsUrl", getResourceUrl("polyfills-es2018.js", "polyfills" + suffix));
78+
replacements.put(
79+
"altairPolyfillsJsUrl", getResourceUrl("polyfills-es2018.js", "polyfills" + suffix));
11580
replacements.put("altairRuntimeJsUrl", getResourceUrl("runtime-es2018.js", "runtime" + suffix));
116-
replacements.put("props", props);
11781
replacements.put("options", objectMapper.writeValueAsString(altairOptions));
118-
replacements.put("headers", headers);
11982
return replacements;
12083
}
12184

@@ -134,20 +97,7 @@ private String getResourceUrl(String staticFileName, String cdnUrl) {
13497
return staticFileName;
13598
}
13699

137-
private String joinJsUnpkgPath(String library, String cdnVersion, String cdnFileName) {
138-
return CDN_JSDELIVR_NET_NPM + library + "@" + cdnVersion + "/" + cdnFileName;
139-
}
140-
141-
private String constructGraphQlEndpoint(
142-
HttpServletRequest request, @RequestParam Map<String, String> params) {
143-
String endpoint = altairProperties.getEndpoint().getGraphql();
144-
for (Map.Entry<String, String> param : params.entrySet()) {
145-
endpoint = endpoint.replaceAll("\\{" + param.getKey() + "}", param.getValue());
146-
}
147-
if (StringUtils.isNotBlank(request.getContextPath())
148-
&& !endpoint.startsWith(request.getContextPath())) {
149-
return request.getContextPath() + endpoint;
150-
}
151-
return endpoint;
100+
private String joinJsdelivrPath(String cdnVersion) {
101+
return CDN_JSDELIVR_NET_NPM + AltairController.ALTAIR + "@" + cdnVersion + "/build/dist/";
152102
}
153103
}

graphql-spring-boot-autoconfigure/src/main/java/graphql/kickstart/autoconfigure/editor/altair/AltairProperties.java

-8
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,11 @@
88
public class AltairProperties {
99

1010
private boolean enabled = false;
11-
private Endpoint endpoint = new Endpoint();
1211
private Cdn cdn = new Cdn();
1312
private String pageTitle = "Altair";
1413
private String mapping = "/altair";
1514
private String basePath = "";
1615

17-
@Data
18-
static class Endpoint {
19-
20-
private String graphql = "/graphql";
21-
private String subscriptions = "/subscriptions";
22-
}
23-
2416
@Data
2517
static class Cdn {
2618

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package graphql.kickstart.autoconfigure.editor.altair;
2+
3+
import java.io.InputStream;
4+
import java.nio.charset.StandardCharsets;
5+
import java.util.Optional;
6+
import lombok.Data;
7+
import lombok.SneakyThrows;
8+
import org.springframework.boot.context.properties.ConfigurationProperties;
9+
import org.springframework.core.io.ClassPathResource;
10+
import org.springframework.core.io.Resource;
11+
import org.springframework.util.StreamUtils;
12+
13+
@Data
14+
@ConfigurationProperties("graphql.altair.resources")
15+
public class AltairResources {
16+
17+
private String initialQuery;
18+
private String initialVariables;
19+
private String initialPreRequestScript;
20+
private String initialPostRequestScript;
21+
22+
public void load(AltairOptions options) {
23+
loadResource(initialQuery).ifPresent(options::setInitialQuery);
24+
loadResource(initialVariables).ifPresent(options::setInitialVariables);
25+
loadResource(initialPreRequestScript).ifPresent(options::setInitialPreRequestScript);
26+
loadResource(initialPostRequestScript).ifPresent(options::setInitialPostRequestScript);
27+
}
28+
29+
private Optional<String> loadResource(String property) {
30+
return Optional.ofNullable(property).map(ClassPathResource::new).map(this::loadResource);
31+
}
32+
33+
@SneakyThrows
34+
private String loadResource(Resource resource) {
35+
try (InputStream inputStream = resource.getInputStream()) {
36+
return StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
37+
}
38+
}
39+
}

graphql-spring-boot-autoconfigure/src/main/resources/templates/altair.html

+1-10
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,8 @@
3333
</div>
3434
</app-root>
3535
<script>
36-
let properties = JSON.parse(`${props}`)
37-
let options = JSON.parse(`${options}`)
38-
let altairConfig = Object.assign({
39-
endpointURL: `${graphqlEndpoint}`,
40-
subscriptionsEndpoint: `${subscriptionsEndpoint}`,
41-
initialQuery: properties.defaultQuery || '',
42-
initialVariables: properties.variables || '',
43-
initialHeaders: JSON.parse(`${headers}`)
44-
}, options || {})
4536
document.addEventListener('DOMContentLoaded', () => {
46-
AltairGraphQL.init(altairConfig)
37+
AltairGraphQL.init(JSON.parse(`${options}`))
4738
})
4839
</script>
4940
<script src="${altairRuntimeJsUrl}" type="text/javascript"></script>

0 commit comments

Comments
 (0)