![JAR search and dependency download from the Maven repository](/logo.png)
graphql.servlet.GraphQLServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of graphql-java-servlet Show documentation
Show all versions of graphql-java-servlet Show documentation
relay.js-compatible GraphQL servlet
/**
* Copyright 2016 Yurii Rashkovskii
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/
package graphql.servlet;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.RuntimeJsonMappingException;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.io.CharStreams;
import graphql.*;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;
import graphql.validation.ValidationError;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import javax.security.auth.Subject;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.stream.Collectors;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLObjectType.newObject;
import static graphql.schema.GraphQLSchema.newSchema;
@Slf4j
@Component(property = {"alias=/graphql", "jmx.objectname=graphql.servlet:type=graphql"})
public class GraphQLServlet extends HttpServlet implements Servlet, GraphQLMBean, GraphQLSchemaProvider {
private List queryProviders = new ArrayList<>();
private List mutationProviders = new ArrayList<>();
@Getter
GraphQLSchema schema;
@Getter
GraphQLSchema readOnlySchema;
protected void updateSchema() {
GraphQLObjectType.Builder object = newObject().name("query");
for (GraphQLQueryProvider provider : queryProviders) {
GraphQLObjectType query = provider.getQuery();
object.field(newFieldDefinition().
type(query).
staticValue(provider.context()).
name(provider.getName()).
description(query.getDescription()).
build());
}
readOnlySchema = newSchema().query(object.build()).build();
if (mutationProviders.isEmpty()) {
schema = readOnlySchema;
} else {
GraphQLObjectType.Builder mutationObject = newObject().name("mutation");
for (GraphQLMutationProvider provider : mutationProviders) {
provider.getMutations().forEach(mutationObject::field);
}
GraphQLObjectType mutationType = mutationObject.build();
if (mutationType.getFieldDefinitions().size() == 0) {
schema = readOnlySchema;
} else {
schema = newSchema().query(object.build()).mutation(mutationType).build();
}
}
}
public GraphQLServlet() {
updateSchema();
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY)
public void bindQueryProvider(GraphQLQueryProvider queryProvider) {
queryProviders.add(queryProvider);
updateSchema();
}
public void unbindQueryProvider(GraphQLQueryProvider queryProvider) {
queryProviders.remove(queryProvider);
updateSchema();
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY)
public void bindMutationProvider(GraphQLMutationProvider mutationProvider) {
mutationProviders.add(mutationProvider);
updateSchema();
}
public void unbindMutationProvider(GraphQLMutationProvider mutationProvider) {
mutationProviders.remove(mutationProvider);
updateSchema();
}
@Override
public String[] getQueries() {
return schema.getQueryType().getFieldDefinitions().stream().map(GraphQLFieldDefinition::getName).toArray(String[]::new);
}
@Override
public String[] getMutations() {
return schema.getMutationType().getFieldDefinitions().stream().map(GraphQLFieldDefinition::getName).toArray(String[]::new);
}
private GraphQLContextBuilder contextBuilder = new DefaultGraphQLContextBuilder();
private ExecutionStrategyProvider executionStrategyProvider = new EnhancedExecutionStrategyProvider();
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
public void setContextProvider(GraphQLContextBuilder contextBuilder) {
this.contextBuilder = contextBuilder;
}
public void unsetContextProvider(GraphQLContextBuilder contextBuilder) {
this.contextBuilder = new DefaultGraphQLContextBuilder();
}
@Reference(cardinality = ReferenceCardinality.OPTIONAL)
public void setExecutionStrategyProvider(ExecutionStrategyProvider provider) {
executionStrategyProvider = provider;
}
public void unsetExecutionStrategyProvider(ExecutionStrategyProvider provider) {
executionStrategyProvider = new EnhancedExecutionStrategyProvider();
}
protected GraphQLContext createContext(Optional req, Optional resp) {
return contextBuilder.build(req, resp);
}
@Override @SneakyThrows
public String executeQuery(String query) {
try {
ExecutionResult result = new GraphQL(schema).execute(query, createContext(Optional.empty(), Optional.empty()), new HashMap<>());
if (result.getErrors().isEmpty()) {
return new ObjectMapper().writeValueAsString(result.getData());
} else {
return new ObjectMapper().writeValueAsString(getGraphQLErrors(result));
}
} catch (Exception e) {
return e.getMessage();
}
}
private static class VariablesDeserializer extends JsonDeserializer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy