Skip to content

Commit 3e88dc0

Browse files
committed
Update to graphql-java 3.0 and use GraphQLSchemaProvider in simple servlet (fixes #29)
1 parent 775ffcf commit 3e88dc0

File tree

10 files changed

+160
-157
lines changed

10 files changed

+160
-157
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ dependencies {
5656
compile 'commons-fileupload:commons-fileupload:1.3.1'
5757

5858
// GraphQL
59-
compile 'com.graphql-java:graphql-java:2.4.0'
59+
compile 'com.graphql-java:graphql-java:3.0.0'
6060

6161
compileOnly 'com.graphql-java:graphql-java-annotations:0.13.1'
6262
testCompile 'com.graphql-java:graphql-java-annotations:0.13.1'
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright 2016 Yurii Rashkovskii
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
*/
15+
package graphql.servlet;
16+
17+
import graphql.schema.GraphQLSchema;
18+
19+
import javax.servlet.http.HttpServletRequest;
20+
21+
/**
22+
* @author Andrew Potter
23+
*/
24+
public class DefaultGraphQLSchemaProvider implements GraphQLSchemaProvider {
25+
26+
private final GraphQLSchema schema;
27+
private final GraphQLSchema readOnlySchema;
28+
29+
public DefaultGraphQLSchemaProvider(GraphQLSchema schema) {
30+
this(schema, GraphQLSchemaProvider.copyReadOnly(schema));
31+
}
32+
33+
public DefaultGraphQLSchemaProvider(GraphQLSchema schema, GraphQLSchema readOnlySchema) {
34+
this.schema = schema;
35+
this.readOnlySchema = readOnlySchema;
36+
}
37+
38+
39+
@Override
40+
public GraphQLSchema getSchema(HttpServletRequest request) {
41+
return getSchema();
42+
}
43+
44+
@Override
45+
public GraphQLSchema getSchema() {
46+
return schema;
47+
}
48+
49+
@Override
50+
public GraphQLSchema getReadOnlySchema(HttpServletRequest request) {
51+
return readOnlySchema;
52+
}
53+
}

src/main/java/graphql/servlet/GraphQLSchemaProvider.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,27 @@
1616

1717
import graphql.schema.GraphQLSchema;
1818

19+
import javax.servlet.http.HttpServletRequest;
20+
1921
public interface GraphQLSchemaProvider {
22+
23+
static GraphQLSchema copyReadOnly(GraphQLSchema schema) {
24+
return GraphQLSchema.newSchema().query(schema.getQueryType()).build(schema.getAdditionalTypes());
25+
}
26+
27+
/**
28+
* return a schema based on the request (auth, etc). Optional is empty when called from an mbean.
29+
*/
30+
GraphQLSchema getSchema(HttpServletRequest request);
31+
32+
33+
/**
34+
* return a schema for handling mbean calls.
35+
*/
2036
GraphQLSchema getSchema();
21-
GraphQLSchema getReadOnlySchema();
37+
38+
/**
39+
* return a read-only schema based on the request (auth, etc). Should return the same schema as {@link #getSchema(HttpServletRequest)} for a given request.
40+
*/
41+
GraphQLSchema getReadOnlySchema(HttpServletRequest request);
2242
}

src/main/java/graphql/servlet/GraphQLServlet.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
import com.fasterxml.jackson.databind.ObjectMapper;
2222
import com.fasterxml.jackson.databind.RuntimeJsonMappingException;
2323
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
24-
import com.google.common.io.CharStreams;
2524
import graphql.ExecutionResult;
25+
import graphql.GraphQL;
2626
import graphql.GraphQLError;
2727
import graphql.InvalidSyntaxError;
2828
import graphql.execution.ExecutionStrategy;
2929
import graphql.execution.instrumentation.Instrumentation;
30+
import graphql.introspection.IntrospectionQuery;
3031
import graphql.schema.GraphQLFieldDefinition;
3132
import graphql.schema.GraphQLSchema;
3233
import graphql.validation.ValidationError;
@@ -45,7 +46,6 @@
4546
import javax.servlet.http.HttpServletResponse;
4647
import java.io.IOException;
4748
import java.io.InputStream;
48-
import java.io.InputStreamReader;
4949
import java.security.AccessController;
5050
import java.security.PrivilegedAction;
5151
import java.util.ArrayList;
@@ -57,12 +57,10 @@
5757
import java.util.function.Consumer;
5858
import java.util.stream.Collectors;
5959

60-
import static graphql.GraphQL.newGraphQL;
61-
6260
/**
6361
* @author Andrew Potter
6462
*/
65-
public abstract class GraphQLServlet extends HttpServlet implements Servlet, GraphQLMBean, GraphQLSchemaProvider {
63+
public abstract class GraphQLServlet extends HttpServlet implements Servlet, GraphQLMBean {
6664

6765
public static final Logger log = LoggerFactory.getLogger(GraphQLServlet.class);
6866

@@ -72,8 +70,10 @@ public abstract class GraphQLServlet extends HttpServlet implements Servlet, Gra
7270

7371
private static final ObjectMapper mapper = new ObjectMapper();
7472

73+
protected abstract GraphQLSchemaProvider getSchemaProvider();
7574
protected abstract GraphQLContext createContext(Optional<HttpServletRequest> request, Optional<HttpServletResponse> response);
76-
protected abstract ExecutionStrategy getExecutionStrategy();
75+
protected abstract ExecutionStrategy getQueryExecutionStrategy();
76+
protected abstract ExecutionStrategy getMutationExecutionStrategy();
7777
protected abstract Instrumentation getInstrumentation();
7878
protected abstract Map<String, Object> transformVariables(GraphQLSchema schema, String query, Map<String, Object> variables);
7979

@@ -100,7 +100,7 @@ public GraphQLServlet(List<GraphQLOperationListener> operationListeners, List<Gr
100100
path = request.getServletPath();
101101
}
102102
if (path.contentEquals("/schema.json")) {
103-
query(CharStreams.toString(new InputStreamReader(GraphQLServlet.class.getResourceAsStream("introspectionQuery"))), null, new HashMap<>(), getSchema(), request, response, context);
103+
query(IntrospectionQuery.INTROSPECTION_QUERY, null, new HashMap<>(), getSchemaProvider().getSchema(request), request, response, context);
104104
} else {
105105
if (request.getParameter("query") != null) {
106106
final Map<String, Object> variables = new HashMap<>();
@@ -111,7 +111,7 @@ public GraphQLServlet(List<GraphQLOperationListener> operationListeners, List<Gr
111111
if (request.getParameter("operationName") != null) {
112112
operationName = request.getParameter("operationName");
113113
}
114-
query(request.getParameter("query"), operationName, variables, getReadOnlySchema(), request, response, context);
114+
query(request.getParameter("query"), operationName, variables, getSchemaProvider().getReadOnlySchema(request), request, response, context);
115115
} else {
116116
response.setStatus(STATUS_BAD_REQUEST);
117117
log.info("Bad GET request: path was not \"/schema.json\" or no query variable named \"query\" given");
@@ -184,7 +184,7 @@ public GraphQLServlet(List<GraphQLOperationListener> operationListeners, List<Gr
184184
variables = new HashMap<>();
185185
}
186186

187-
query(graphQLRequest.getQuery(), graphQLRequest.getOperationName(), variables, getSchema(), request, response, context);
187+
query(graphQLRequest.getQuery(), graphQLRequest.getOperationName(), variables, getSchemaProvider().getSchema(request), request, response, context);
188188
};
189189
}
190190

@@ -206,18 +206,18 @@ public void removeServletListener(GraphQLServletListener servletListener) {
206206

207207
@Override
208208
public String[] getQueries() {
209-
return getSchema().getQueryType().getFieldDefinitions().stream().map(GraphQLFieldDefinition::getName).toArray(String[]::new);
209+
return getSchemaProvider().getSchema().getQueryType().getFieldDefinitions().stream().map(GraphQLFieldDefinition::getName).toArray(String[]::new);
210210
}
211211

212212
@Override
213213
public String[] getMutations() {
214-
return getSchema().getMutationType().getFieldDefinitions().stream().map(GraphQLFieldDefinition::getName).toArray(String[]::new);
214+
return getSchemaProvider().getSchema().getMutationType().getFieldDefinitions().stream().map(GraphQLFieldDefinition::getName).toArray(String[]::new);
215215
}
216216

217217
@Override
218218
public String executeQuery(String query) {
219219
try {
220-
final ExecutionResult result = newGraphQL(getSchema()).instrumentation(getInstrumentation()).build().execute(query, createContext(Optional.empty(), Optional.empty()), new HashMap<>());
220+
final ExecutionResult result = newGraphQL(getSchemaProvider().getSchema()).execute(query, createContext(Optional.empty(), Optional.empty()), new HashMap<>());
221221
return mapper.writeValueAsString(createResultFromDataAndErrors(result.getData(), result.getErrors()));
222222
} catch (Exception e) {
223223
return e.getMessage();
@@ -257,6 +257,13 @@ private Optional<FileItem> getFileItem(Map<String, List<FileItem>> fileItems, St
257257
return items.stream().findFirst();
258258
}
259259

260+
private GraphQL newGraphQL(GraphQLSchema schema) {
261+
return GraphQL.newGraphQL(schema)
262+
.queryExecutionStrategy(getQueryExecutionStrategy())
263+
.mutationExecutionStrategy(getMutationExecutionStrategy())
264+
.instrumentation(getInstrumentation())
265+
.build();
266+
}
260267

261268
private void query(String query, String operationName, Map<String, Object> variables, GraphQLSchema schema, HttpServletRequest req, HttpServletResponse resp, GraphQLContext context) throws IOException {
262269
if (Subject.getSubject(AccessController.getContext()) == null && context.getSubject().isPresent()) {
@@ -271,7 +278,7 @@ private void query(String query, String operationName, Map<String, Object> varia
271278
} else {
272279
runListeners(operationListeners, l -> runListener(l, it -> it.beforeGraphQLOperation(context, operationName, query, variables)));
273280

274-
final ExecutionResult executionResult = newGraphQL(schema).queryExecutionStrategy(getExecutionStrategy()).instrumentation(getInstrumentation()).build().execute(query, operationName, context, transformVariables(schema, query, variables));
281+
final ExecutionResult executionResult = newGraphQL(schema).execute(query, operationName, context, transformVariables(schema, query, variables));
275282
final List<GraphQLError> errors = executionResult.getErrors();
276283
final Object data = executionResult.getData();
277284

src/main/java/graphql/servlet/OsgiGraphQLServlet.java

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,14 @@ public class OsgiGraphQLServlet extends GraphQLServlet {
5151
private ExecutionStrategyProvider executionStrategyProvider = new EnhancedExecutionStrategyProvider();
5252
private InstrumentationProvider instrumentationProvider = new NoOpInstrumentationProvider();
5353

54-
private GraphQLSchema schema;
55-
private GraphQLSchema readOnlySchema;
54+
private GraphQLSchemaProvider schemaProvider;
5655

5756
protected void updateSchema() {
58-
final GraphQLObjectType.Builder object = newObject().name("Query").description("Root query type");
57+
final GraphQLObjectType.Builder queryTypeBuilder = newObject().name("Query").description("Root query type");
5958

6059
for (GraphQLQueryProvider provider : queryProviders) {
6160
if (provider.getQueries() != null && !provider.getQueries().isEmpty()) {
62-
for (GraphQLFieldDefinition graphQLFieldDefinition : provider.getQueries()) {
63-
object.field(graphQLFieldDefinition);
64-
}
61+
provider.getQueries().forEach(queryTypeBuilder::field);
6562
}
6663
}
6764

@@ -70,24 +67,21 @@ protected void updateSchema() {
7067
types.addAll(typesProvider.getTypes());
7168
}
7269

73-
readOnlySchema = newSchema().query(object.build()).build(types);
70+
GraphQLObjectType mutationType = null;
7471

75-
if (mutationProviders.isEmpty()) {
76-
schema = readOnlySchema;
77-
} else {
78-
final GraphQLObjectType.Builder mutationObject = newObject().name("Mutation").description("Root mutation type");
72+
if (!mutationProviders.isEmpty()) {
73+
final GraphQLObjectType.Builder mutationTypeBuilder = newObject().name("Mutation").description("Root mutation type");
7974

8075
for (GraphQLMutationProvider provider : mutationProviders) {
81-
provider.getMutations().forEach(mutationObject::field);
76+
provider.getMutations().forEach(mutationTypeBuilder::field);
8277
}
8378

84-
final GraphQLObjectType mutationType = mutationObject.build();
85-
if (mutationType.getFieldDefinitions().isEmpty()) {
86-
schema = readOnlySchema;
87-
} else {
88-
schema = newSchema().query(object.build()).mutation(mutationType).build();
79+
if (!mutationTypeBuilder.build().getFieldDefinitions().isEmpty()) {
80+
mutationType = mutationTypeBuilder.build();
8981
}
9082
}
83+
84+
this.schemaProvider = new DefaultGraphQLSchemaProvider(newSchema().query(queryTypeBuilder.build()).mutation(mutationType).build(types));
9185
}
9286

9387
public OsgiGraphQLServlet() {
@@ -148,15 +142,25 @@ public void unsetInstrumentationProvider(ExecutionStrategyProvider provider) {
148142
instrumentationProvider = new NoOpInstrumentationProvider();
149143
}
150144

145+
@Override
146+
protected GraphQLSchemaProvider getSchemaProvider() {
147+
return schemaProvider;
148+
}
149+
151150
protected GraphQLContext createContext(Optional<HttpServletRequest> req, Optional<HttpServletResponse> resp) {
152151
return contextBuilder.build(req, resp);
153152
}
154153

155154
@Override
156-
protected ExecutionStrategy getExecutionStrategy() {
155+
protected ExecutionStrategy getQueryExecutionStrategy() {
157156
return executionStrategyProvider.getExecutionStrategy();
158157
}
159158

159+
@Override
160+
protected ExecutionStrategy getMutationExecutionStrategy() {
161+
return getQueryExecutionStrategy();
162+
}
163+
160164
@Override
161165
protected Instrumentation getInstrumentation() {
162166
return instrumentationProvider.getInstrumentation();
@@ -175,14 +179,4 @@ public void bindOperationListener(GraphQLOperationListener listener) {
175179
public void unbindOperationListener(GraphQLOperationListener listener) {
176180
removeOperationListener(listener);
177181
}
178-
179-
@Override
180-
public GraphQLSchema getSchema() {
181-
return schema;
182-
}
183-
184-
@Override
185-
public GraphQLSchema getReadOnlySchema() {
186-
return readOnlySchema;
187-
}
188182
}

0 commit comments

Comments
 (0)