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

Commit b6cee6a

Browse files
authored
Merge pull request #600 from graphql-java-kickstart/feature/voyager-latest
Voyager configuration options
2 parents 92bc41c + e39cdeb commit b6cee6a

File tree

9 files changed

+173
-37
lines changed

9 files changed

+173
-37
lines changed

README.md

+61-1
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@ and join the team!
2828
- [Enable GraphQL Servlet](#enable-graphql-servlet)
2929
- [Enable Graph*i*QL](#enable-graphiql)
3030
- [Enable Altair](#enable-altair)
31-
- [Enable GraphQL Playground](#enable-graphql-playground)
31+
- [Enable GraphQL Playground](#enable-graphql-voyager)
3232
- [Basic settings](#basic-settings)
3333
- [CDN](#cdn)
3434
- [Custom static resources](#custom-static-resources)
3535
- [Customizing GraphQL Playground](#customizing-graphql-playground)
3636
- [Tabs](#tabs)
37+
- [Enable GraphQL Voyager](#enable-graphql-playground)
38+
- [Basic settings](#graphql-voyager-basic-settings)
39+
- [CDN](#graphql-voyager-cdn)
40+
- [Customizing GraphQL Voyager](#customizing-graphql-voyager)
3741
- [Supported GraphQL-Java Libraries](#supported-graphql-java-libraries)
3842
- [GraphQL Java Tools](#graphql-java-tools)
3943
- [GraphQL Annotations](#graphql-annotations)
@@ -433,6 +437,62 @@ You can configure the query, variables, headers and even supply sample responses
433437
, `variables` and `responses` are expected to be resources of the appropriate format (GraphQL
434438
for `query`, JSON for `variables` and `responses`).
435439

440+
441+
# Enable GraphQL Voyager
442+
443+
**GraphQL Voyager** becomes accessible at root `/voyager` (or as configured
444+
in `voyager.mapping`)
445+
if `voyager-spring-boot-starter` is added as a dependency to a boot application.
446+
447+
Available Spring Boot configuration parameters (either `application.yml`
448+
or `application.properties`):
449+
450+
```yaml
451+
voyager:
452+
enabled: true
453+
basePath: /
454+
mapping: /voyager
455+
endpoint: /graphql
456+
cdn:
457+
enabled: false
458+
version: latest
459+
pageTitle: Voyager
460+
displayOptions:
461+
skipRelay: true
462+
skipDeprecated: true
463+
rootType: Query
464+
sortByAlphabet: false
465+
showLeafFields: true
466+
hideRoot: false
467+
hideDocs: false
468+
hideSettings: false
469+
```
470+
471+
## GraphQL Voyager Basic settings
472+
473+
`mapping` and `endpoint` will default to `/voyager` and `/graphql`, respectively. Note that these values may not be empty.
474+
475+
`enabled` defaults to `true`, and therefor **GraphQL Voyager** will be available by default if the dependency
476+
is added to a Spring Boot Web Application project.
477+
478+
`pageTitle` defaults to `Voyager`.
479+
480+
All other properties default to the same as documented on the official [GraphQL Voyager readme](https://github.com/APIs-guru/graphql-voyager#properties)
481+
482+
## GraphQL Voyager CDN
483+
484+
The currently bundled version is `1.0.0-rc31`, which is - as of writing this - the latest release
485+
of **GraphQL Voyager**. The CDN option uses `jsDelivr` CDN, if enabled. By default, it will
486+
load the latest available release. Available CDN versions can be found on the project's
487+
[jsDelivr page](https://www.jsdelivr.com/package/npm/graphql-voyager). The CDN option is
488+
disabled by default.
489+
490+
## Customizing GraphQL Voyager
491+
492+
Further **GraphQL Voyager** `displayOptions`, `hideDocs` and `hideSettings` customizations can be configured, as documented in the official
493+
[GraphQL Voyager readme](https://github.com/APIs-guru/graphql-voyager#properties).
494+
495+
436496
# Supported GraphQL-Java Libraries
437497

438498
The following libraries have auto-configuration classes for creating a `GraphQLSchema`.

voyager-spring-boot-autoconfigure/src/main/java/graphql/kickstart/voyager/boot/ReactiveVoyagerAutoConfiguration.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package graphql.kickstart.voyager.boot;
22

3-
import org.springframework.beans.factory.annotation.Value;
43
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
54
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
5+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
66
import org.springframework.context.annotation.Bean;
77
import org.springframework.context.annotation.Configuration;
88
import org.springframework.core.io.ClassPathResource;
@@ -16,11 +16,9 @@
1616
@Configuration
1717
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
1818
@ConditionalOnProperty(value = "voyager.enabled", havingValue = "true", matchIfMissing = true)
19+
@EnableConfigurationProperties(VoyagerPropertiesConfiguration.class)
1920
public class ReactiveVoyagerAutoConfiguration {
2021

21-
@Value("${voyager.mapping:/voyager}")
22-
private String voyagerPath;
23-
2422
@Bean
2523
ReactiveVoyagerController voyagerController() {
2624
return new ReactiveVoyagerController();
@@ -35,7 +33,7 @@ public RouterFunction<ServerResponse> voyagerStaticFilesRouter() {
3533
}
3634

3735
@Bean
38-
VoyagerIndexHtmlTemplate voyagerIndexHtmlTemplate() {
39-
return new VoyagerIndexHtmlTemplate();
36+
VoyagerIndexHtmlTemplate voyagerIndexHtmlTemplate(final VoyagerPropertiesConfiguration voyagerPropertiesConfiguration) {
37+
return new VoyagerIndexHtmlTemplate(voyagerPropertiesConfiguration);
4038
}
4139
}

voyager-spring-boot-autoconfigure/src/main/java/graphql/kickstart/voyager/boot/ReactiveVoyagerController.java

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.IOException;
44
import java.util.Map;
5+
import lombok.RequiredArgsConstructor;
56
import org.springframework.beans.factory.annotation.Autowired;
67
import org.springframework.http.MediaType;
78
import org.springframework.http.ResponseEntity;
@@ -13,6 +14,7 @@
1314
* @author Max David Günther
1415
*/
1516
@Controller
17+
@RequiredArgsConstructor
1618
public class ReactiveVoyagerController {
1719

1820
@Autowired

voyager-spring-boot-autoconfigure/src/main/java/graphql/kickstart/voyager/boot/VoyagerAutoConfiguration.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
44
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
5+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
56
import org.springframework.context.annotation.Bean;
67
import org.springframework.context.annotation.Configuration;
78

@@ -11,6 +12,7 @@
1112
@Configuration
1213
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
1314
@ConditionalOnProperty(value = "voyager.enabled", havingValue = "true", matchIfMissing = true)
15+
@EnableConfigurationProperties(VoyagerPropertiesConfiguration.class)
1416
public class VoyagerAutoConfiguration {
1517

1618
@Bean
@@ -19,7 +21,7 @@ VoyagerController voyagerController() {
1921
}
2022

2123
@Bean
22-
VoyagerIndexHtmlTemplate voyagerIndexHtmlTemplate() {
23-
return new VoyagerIndexHtmlTemplate();
24+
VoyagerIndexHtmlTemplate voyagerIndexHtmlTemplate(final VoyagerPropertiesConfiguration voyagerPropertiesConfiguration) {
25+
return new VoyagerIndexHtmlTemplate(voyagerPropertiesConfiguration);
2426
}
2527
}

voyager-spring-boot-autoconfigure/src/main/java/graphql/kickstart/voyager/boot/VoyagerIndexHtmlTemplate.java

+29-26
Original file line numberDiff line numberDiff line change
@@ -4,70 +4,73 @@
44
import java.nio.charset.Charset;
55
import java.util.HashMap;
66
import java.util.Map;
7+
import lombok.RequiredArgsConstructor;
78
import org.apache.commons.lang3.StringUtils;
89
import org.apache.commons.text.StringSubstitutor;
9-
import org.springframework.beans.factory.annotation.Value;
1010
import org.springframework.core.io.ClassPathResource;
1111
import org.springframework.util.StreamUtils;
1212
import org.springframework.web.bind.annotation.RequestParam;
1313

1414
/**
1515
* @author Guilherme Blanco
1616
*/
17+
@RequiredArgsConstructor
1718
public class VoyagerIndexHtmlTemplate {
1819

1920
private static final String CDNJS_CLOUDFLARE_COM_AJAX_LIBS = "//cdnjs.cloudflare.com/ajax/libs/";
2021
private static final String CDN_JSDELIVR_NET_NPM = "//cdn.jsdelivr.net/npm/";
2122
private static final String VOYAGER = "graphql-voyager";
2223
private static final String FAVICON_APIS_GURU = "//apis.guru/graphql-voyager/icons/favicon-16x16.png";
2324

24-
@Value("${voyager.endpoint:/graphql}")
25-
private String graphqlEndpoint;
26-
27-
@Value("${voyager.pageTitle:Voyager}")
28-
private String pageTitle;
29-
30-
@Value("${voyager.static.basePath:/}")
31-
private String staticBasePath;
32-
33-
@Value("${voyager.cdn.enabled:false}")
34-
private boolean voyagerCdnEnabled;
35-
36-
@Value("${voyager.cdn.version:1.0.0-rc.31}")
37-
private String voyagerCdnVersion;
25+
private final VoyagerPropertiesConfiguration voyagerConfiguration;
3826

3927
public String fillIndexTemplate(String contextPath, Map<String, String> params)
4028
throws IOException {
4129
String template = StreamUtils
4230
.copyToString(new ClassPathResource("voyager.html").getInputStream(),
4331
Charset.defaultCharset());
32+
33+
String basePath = voyagerConfiguration.getBasePath();
34+
String voyagerCdnVersion = voyagerConfiguration.getCdn().getVersion();
35+
4436
Map<String, String> replacements = new HashMap<>();
4537
replacements.put("graphqlEndpoint", constructGraphQlEndpoint(contextPath, params));
46-
replacements.put("pageTitle", pageTitle);
38+
replacements.put("pageTitle", voyagerConfiguration.getPageTitle());
4739
replacements
48-
.put("pageFavicon", getResourceUrl(staticBasePath, "favicon.ico", FAVICON_APIS_GURU));
49-
replacements.put("es6PromiseJsUrl", getResourceUrl(staticBasePath, "es6-promise.auto.min.js",
40+
.put("pageFavicon", getResourceUrl(basePath, "favicon.ico", FAVICON_APIS_GURU));
41+
replacements.put("es6PromiseJsUrl", getResourceUrl(basePath, "es6-promise.auto.min.js",
5042
joinCdnjsPath("es6-promise", "4.1.1", "es6-promise.auto.min.js")));
51-
replacements.put("fetchJsUrl", getResourceUrl(staticBasePath, "fetch.min.js",
43+
replacements.put("fetchJsUrl", getResourceUrl(basePath, "fetch.min.js",
5244
joinCdnjsPath("fetch", "2.0.4", "fetch.min.js")));
53-
replacements.put("reactJsUrl", getResourceUrl(staticBasePath, "react.min.js",
45+
replacements.put("reactJsUrl", getResourceUrl(basePath, "react.min.js",
5446
joinCdnjsPath("react", "16.8.3", "umd/react.production.min.js")));
55-
replacements.put("reactDomJsUrl", getResourceUrl(staticBasePath, "react-dom.min.js",
47+
replacements.put("reactDomJsUrl", getResourceUrl(basePath, "react-dom.min.js",
5648
joinCdnjsPath("react-dom", "16.8.3", "umd/react-dom.production.min.js")));
57-
replacements.put("voyagerCssUrl", getResourceUrl(staticBasePath, "voyager.css",
49+
replacements.put("voyagerCssUrl", getResourceUrl(basePath, "voyager.css",
5850
joinJsDelivrPath(voyagerCdnVersion, "dist/voyager.css")));
59-
replacements.put("voyagerJsUrl", getResourceUrl(staticBasePath, "voyager.min.js",
51+
replacements.put("voyagerJsUrl", getResourceUrl(basePath, "voyager.min.js",
6052
joinJsDelivrPath(voyagerCdnVersion, "dist/voyager.min.js")));
61-
replacements.put("voyagerWorkerJsUrl", getResourceUrl(staticBasePath, "voyager.worker.js",
53+
replacements.put("voyagerWorkerJsUrl", getResourceUrl(basePath, "voyager.worker.js",
6254
joinJsDelivrPath(voyagerCdnVersion, "dist/voyager.worker.min.js")));
6355
replacements.put("contextPath", contextPath);
56+
replacements.put("voyagerDisplayOptionsSkipRelay", Boolean.toString(voyagerConfiguration.getDisplayOptions().isSkipRelay()));
57+
replacements.put("voyagerDisplayOptionsSkipDeprecated", Boolean.toString(voyagerConfiguration.getDisplayOptions().isSkipDeprecated()));
58+
replacements.put("voyagerDisplayOptionsRootType", voyagerConfiguration.getDisplayOptions().getRootType());
59+
replacements.put("voyagerDisplayOptionsSortByAlphabet", Boolean.toString(
60+
voyagerConfiguration.getDisplayOptions().isSortByAlphabet()));
61+
replacements.put("voyagerDisplayOptionsShowLeafFields", Boolean.toString(voyagerConfiguration.getDisplayOptions().isShowLeafFields()));
62+
replacements.put("voyagerDisplayOptionsHideRoot", Boolean.toString(voyagerConfiguration.getDisplayOptions().isHideRoot()));
63+
replacements.put("voyagerHideDocs", Boolean.toString(voyagerConfiguration.isHideDocs()));
64+
replacements.put("voyagerHideSettings", Boolean.toString(voyagerConfiguration.isHideSettings()));
65+
66+
6467

6568
return StringSubstitutor.replace(template, replacements);
6669
}
6770

6871
private String constructGraphQlEndpoint(String contextPath,
6972
@RequestParam Map<String, String> params) {
70-
String endpoint = graphqlEndpoint;
73+
String endpoint = voyagerConfiguration.getEndpoint();
7174
for (Map.Entry<String, String> param : params.entrySet()) {
7275
endpoint = endpoint.replaceAll("\\{" + param.getKey() + "}", param.getValue());
7376
}
@@ -78,7 +81,7 @@ private String constructGraphQlEndpoint(String contextPath,
7881
}
7982

8083
private String getResourceUrl(String staticBasePath, String staticFileName, String cdnUrl) {
81-
if (voyagerCdnEnabled && StringUtils.isNotBlank(cdnUrl)) {
84+
if (voyagerConfiguration.getCdn().isEnabled() && StringUtils.isNotBlank(cdnUrl)) {
8285
return cdnUrl;
8386
}
8487
return joinStaticPath(staticBasePath, staticFileName);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package graphql.kickstart.voyager.boot;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnore;
4+
import graphql.kickstart.voyager.boot.properties.VoyagerCdn;
5+
import graphql.kickstart.voyager.boot.properties.VoyagerDisplayOptions;
6+
import lombok.Data;
7+
import org.springframework.boot.context.properties.ConfigurationProperties;
8+
import org.springframework.boot.context.properties.NestedConfigurationProperty;
9+
import org.springframework.validation.annotation.Validated;
10+
11+
12+
@Data
13+
@ConfigurationProperties(prefix = "voyager")
14+
@Validated
15+
public class VoyagerPropertiesConfiguration {
16+
17+
private String endpoint = "/graphql";
18+
19+
private String pageTitle = "Voyager";
20+
21+
private String basePath = "/";
22+
23+
@NestedConfigurationProperty
24+
@JsonIgnore
25+
private VoyagerCdn cdn = new VoyagerCdn();
26+
27+
@NestedConfigurationProperty
28+
@JsonIgnore
29+
private VoyagerDisplayOptions displayOptions = new VoyagerDisplayOptions();
30+
31+
@JsonIgnore
32+
private boolean hideDocs;
33+
34+
@JsonIgnore
35+
private boolean hideSettings;
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package graphql.kickstart.voyager.boot.properties;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class VoyagerCdn {
7+
8+
private boolean enabled;
9+
private String version = "latest";
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package graphql.kickstart.voyager.boot.properties;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import lombok.Data;
5+
6+
@Data
7+
@JsonInclude(JsonInclude.Include.NON_NULL)
8+
public class VoyagerDisplayOptions {
9+
10+
private boolean skipRelay = true;
11+
private boolean skipDeprecated = true;
12+
private String rootType = "Query";
13+
private boolean sortByAlphabet = false;
14+
private boolean showLeafFields = true;
15+
private boolean hideRoot = false;
16+
17+
}

voyager-spring-boot-autoconfigure/src/main/resources/voyager.html

+9-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,15 @@ <h1> Transmitting... </h1>
7373
GraphQLVoyager.init(document.getElementById('voyager'), {
7474
introspection: introspectionProvider,
7575
displayOptions: {
76-
sortByAlphabet: true,
77-
}
76+
skipRelay: ${voyagerDisplayOptionsSkipRelay},
77+
skipDeprecated: ${voyagerDisplayOptionsSkipDeprecated},
78+
rootType: '${voyagerDisplayOptionsRootType}',
79+
sortByAlphabet: ${voyagerDisplayOptionsSortByAlphabet},
80+
showLeafFields: ${voyagerDisplayOptionsShowLeafFields},
81+
hideRoot: ${voyagerDisplayOptionsHideRoot},
82+
},
83+
hideDocs: ${voyagerHideDocs},
84+
hideSettings: ${voyagerHideSettings},
7885
})
7986
</script>
8087
</body>

0 commit comments

Comments
 (0)