kandi background
Explore Kits

graphql-java | GraphQL Java implementation | GraphQL library

 by   graphql-java Java Version: v18.0 License: MIT

 by   graphql-java Java Version: v18.0 License: MIT

Download this library from

kandi X-RAY | graphql-java Summary

graphql-java is a Java library typically used in Web Services, GraphQL applications. graphql-java has no bugs, it has no vulnerabilities, it has build file available, it has a Permissive License and it has high support. You can download it from GitHub, Maven.
Discuss and ask questions in our Discussions: https://github.com/graphql-java/graphql-java/discussions. This is a GraphQL Java implementation.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • graphql-java has a highly active ecosystem.
  • It has 5458 star(s) with 1001 fork(s). There are 221 watchers for this library.
  • There were 1 major release(s) in the last 6 months.
  • There are 76 open issues and 1017 have been closed. On average issues are closed in 69 days. There are 24 open pull requests and 0 closed requests.
  • It has a positive sentiment in the developer community.
  • The latest version of graphql-java is v18.0
graphql-java Support
Best in #GraphQL
Average in #GraphQL
graphql-java Support
Best in #GraphQL
Average in #GraphQL

quality kandi Quality

  • graphql-java has 0 bugs and 0 code smells.
graphql-java Quality
Best in #GraphQL
Average in #GraphQL
graphql-java Quality
Best in #GraphQL
Average in #GraphQL

securitySecurity

  • graphql-java has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • graphql-java code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
graphql-java Security
Best in #GraphQL
Average in #GraphQL
graphql-java Security
Best in #GraphQL
Average in #GraphQL

license License

  • graphql-java is licensed under the MIT License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
graphql-java License
Best in #GraphQL
Average in #GraphQL
graphql-java License
Best in #GraphQL
Average in #GraphQL

buildReuse

  • graphql-java releases are available to install and integrate.
  • Deployable package is available in Maven.
  • Build file is available. You can build the component from source.
  • graphql-java saves you 24922 person hours of effort in developing the same functionality from scratch.
  • It has 51760 lines of code, 6112 functions and 615 files.
  • It has medium code complexity. Code complexity directly impacts maintainability of the code.
graphql-java Reuse
Best in #GraphQL
Average in #GraphQL
graphql-java Reuse
Best in #GraphQL
Average in #GraphQL
Top functions reviewed by kandi - BETA

kandi has reviewed graphql-java and discovered the below as its top functions. This is intended to give you an instant insight into graphql-java implemented functionality, and help decide if they suit your requirements.

  • Records new namespaces .
  • Sorts the given node .
  • Traverses and transforms a dummy node .
  • Traverses the given collection of roots .
  • Checks a type .
  • Create valid rules .
  • Merge a type registry .
  • Executes the given operation .
  • Fetch field .
  • Moves the node from the same parent .

graphql-java Key Features

GraphQL Java implementation

How to handle custom GraphQL error such that it does not display the exception stack trace in Java

copy iconCopydownload iconDownload
public class GraphqlDremioClientException extends RuntimeException implements GraphQLError {

    private static final long serialVersionUID = 1L;
    
    private final String message;
    
    private boolean writeStacktrace = false;

    @Override
    public String getMessage() {
        return message;
    }
    /* other constructors */
        
    public GraphqlDremioClientException(String message, boolean writeStacktrace) {
        super(message, null, false, writeStacktrace);
        this.writeStacktrace = writeStacktrace;
        this.message = message;
    }
    
    public GraphqlDremioClientException(String message, Exception ex) {
        super();
        this.message = message;
    }

    @Override
    public List<SourceLocation> getLocations() {
        return null;
    }

    @Override
    public ErrorType getErrorType() {
        return null;
    }       
}
@Slf4j
@Component
public class CustomGraphqlErrorHandler implements GraphQLErrorHandler {

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> list) {
        return list.stream().map(this::getNested).collect(Collectors.toList());
    }
    
    private GraphQLError getNested(GraphQLError error) {
        log.error(error.getMessage(), error);
        
        if (error instanceof ExceptionWhileDataFetching) {
            ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
            if (exceptionError.getException() instanceof GraphQLError) {
                return new GraphqlDremioClientException(exceptionError.getMessage(), false);
            }
        }
        return error;
    }
}
{
    "data": {
        "CommercialAsset": null
    },
    "errors": [
        {
            "cause": null,
            "stackTrace": [],
            "message": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source",
            "writeStacktrace": false,
            "locations": null,
            "errorType": null,
            "path": null,
            "extensions": null,
            "suppressed": [],
            "localizedMessage": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source"
        }
    ]
}
-----------------------
public class GraphqlDremioClientException extends RuntimeException implements GraphQLError {

    private static final long serialVersionUID = 1L;
    
    private final String message;
    
    private boolean writeStacktrace = false;

    @Override
    public String getMessage() {
        return message;
    }
    /* other constructors */
        
    public GraphqlDremioClientException(String message, boolean writeStacktrace) {
        super(message, null, false, writeStacktrace);
        this.writeStacktrace = writeStacktrace;
        this.message = message;
    }
    
    public GraphqlDremioClientException(String message, Exception ex) {
        super();
        this.message = message;
    }

    @Override
    public List<SourceLocation> getLocations() {
        return null;
    }

    @Override
    public ErrorType getErrorType() {
        return null;
    }       
}
@Slf4j
@Component
public class CustomGraphqlErrorHandler implements GraphQLErrorHandler {

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> list) {
        return list.stream().map(this::getNested).collect(Collectors.toList());
    }
    
    private GraphQLError getNested(GraphQLError error) {
        log.error(error.getMessage(), error);
        
        if (error instanceof ExceptionWhileDataFetching) {
            ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
            if (exceptionError.getException() instanceof GraphQLError) {
                return new GraphqlDremioClientException(exceptionError.getMessage(), false);
            }
        }
        return error;
    }
}
{
    "data": {
        "CommercialAsset": null
    },
    "errors": [
        {
            "cause": null,
            "stackTrace": [],
            "message": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source",
            "writeStacktrace": false,
            "locations": null,
            "errorType": null,
            "path": null,
            "extensions": null,
            "suppressed": [],
            "localizedMessage": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source"
        }
    ]
}
-----------------------
public class GraphqlDremioClientException extends RuntimeException implements GraphQLError {

    private static final long serialVersionUID = 1L;
    
    private final String message;
    
    private boolean writeStacktrace = false;

    @Override
    public String getMessage() {
        return message;
    }
    /* other constructors */
        
    public GraphqlDremioClientException(String message, boolean writeStacktrace) {
        super(message, null, false, writeStacktrace);
        this.writeStacktrace = writeStacktrace;
        this.message = message;
    }
    
    public GraphqlDremioClientException(String message, Exception ex) {
        super();
        this.message = message;
    }

    @Override
    public List<SourceLocation> getLocations() {
        return null;
    }

    @Override
    public ErrorType getErrorType() {
        return null;
    }       
}
@Slf4j
@Component
public class CustomGraphqlErrorHandler implements GraphQLErrorHandler {

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> list) {
        return list.stream().map(this::getNested).collect(Collectors.toList());
    }
    
    private GraphQLError getNested(GraphQLError error) {
        log.error(error.getMessage(), error);
        
        if (error instanceof ExceptionWhileDataFetching) {
            ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
            if (exceptionError.getException() instanceof GraphQLError) {
                return new GraphqlDremioClientException(exceptionError.getMessage(), false);
            }
        }
        return error;
    }
}
{
    "data": {
        "CommercialAsset": null
    },
    "errors": [
        {
            "cause": null,
            "stackTrace": [],
            "message": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source",
            "writeStacktrace": false,
            "locations": null,
            "errorType": null,
            "path": null,
            "extensions": null,
            "suppressed": [],
            "localizedMessage": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source"
        }
    ]
}

graphql-spring-boot-starter Application with only websockets

copy iconCopydownload iconDownload
@RestController
@RequestMapping("/")
public class WebSocketController
{

    private static final Logger logger = LoggerFactory.getLogger(WebSocketController.class);

    private final GraphQLObjectMapper objectMapper;

    private final GraphQLInvoker graphQLInvoker;

    private final GraphQLSpringInvocationInputFactory invocationInputFactory;

    private final WebSocketService service;

    @Autowired
    public WebSocketController(GraphQLObjectMapper objectMapper, GraphQLInvoker graphQLInvoker,
            GraphQLSpringInvocationInputFactory invocationInputFactory, WebSocketService service)
    {
        this.objectMapper = objectMapper;
        this.graphQLInvoker = graphQLInvoker;
        this.invocationInputFactory = invocationInputFactory;
        this.service = service;
    }

    @GetMapping("${graphql.websocket.path:graphql-ws}")
    public Mono<Void> getMono(ServerWebExchange exchange)
    {
        logger.debug("New connection via GET");
        return service.handleRequest(exchange,
                new GraphQLWebsocketMessageConsumer(exchange, objectMapper, graphQLInvoker, invocationInputFactory));
    }

    @PostMapping("${graphql.websocket.path:graphql-ws}")
    public Mono<Void> postMono(ServerWebExchange exchange)
    {
        ...
    }

}
public class GraphQLWebsocketMessageConsumer implements Consumer<String>, WebSocketHandler
{

    private static final Logger logger = LoggerFactory.getLogger(GraphQLWebsocketMessageConsumer.class);

    private final ServerWebExchange swe;

    private final GraphQLObjectMapper objectMapper;

    private final GraphQLInvoker graphQLInvoker;

    private final GraphQLSpringInvocationInputFactory invocationInputFactory;

    private final Sinks.Many<String> publisher;

    public GraphQLWebsocketMessageConsumer(ServerWebExchange swe, GraphQLObjectMapper objectMapper,
            GraphQLInvoker graphQLInvoker, GraphQLSpringInvocationInputFactory invocationInputFactory)
    {
        ...
        publisher = Sinks.many().multicast().directBestEffort();
    }

    @Override
    public Mono<Void> handle(WebSocketSession webSocketSession)
    {
        Mono<Void> input = webSocketSession.receive().map(WebSocketMessage::getPayloadAsText).doOnNext(this).then();
        Mono<Void> sender = webSocketSession.send(publisher.asFlux().map(webSocketSession::textMessage));
        return Mono.zip(input, sender).then();
    }

    @Override
    public void accept(String body)
    {
        try
        {
            String query = extractQuery(body);
            if(query == null)
            {
                return;
            }
            GraphQLRequest request = objectMapper.readGraphQLRequest(query);
            GraphQLSingleInvocationInput invocationInput = invocationInputFactory.create(request, swe);
            Mono<ExecutionResult> executionResult = Mono.fromCompletionStage(graphQLInvoker.executeAsync(invocationInput));
            Mono<String> jsonResult = executionResult.map(objectMapper::serializeResultAsJson);
            jsonResult.subscribe(publisher::tryEmitNext);
        } catch (Exception e)
        {
            ...
        }
    }

    @SuppressWarnings("unchecked")
    private String extractQuery(final String query) throws Exception
    {
        Map<String, Object> map = (Map<String, Object>) objectMapper.getJacksonMapper().readValue(query, Map.class);
        ...
        return queryPart;
    }

    @Override
    public List<String> getSubProtocols()
    {
        logger.debug("getSubProtocols called");
        return Collections.singletonList("graphql-ws");
    }

}
-----------------------
@RestController
@RequestMapping("/")
public class WebSocketController
{

    private static final Logger logger = LoggerFactory.getLogger(WebSocketController.class);

    private final GraphQLObjectMapper objectMapper;

    private final GraphQLInvoker graphQLInvoker;

    private final GraphQLSpringInvocationInputFactory invocationInputFactory;

    private final WebSocketService service;

    @Autowired
    public WebSocketController(GraphQLObjectMapper objectMapper, GraphQLInvoker graphQLInvoker,
            GraphQLSpringInvocationInputFactory invocationInputFactory, WebSocketService service)
    {
        this.objectMapper = objectMapper;
        this.graphQLInvoker = graphQLInvoker;
        this.invocationInputFactory = invocationInputFactory;
        this.service = service;
    }

    @GetMapping("${graphql.websocket.path:graphql-ws}")
    public Mono<Void> getMono(ServerWebExchange exchange)
    {
        logger.debug("New connection via GET");
        return service.handleRequest(exchange,
                new GraphQLWebsocketMessageConsumer(exchange, objectMapper, graphQLInvoker, invocationInputFactory));
    }

    @PostMapping("${graphql.websocket.path:graphql-ws}")
    public Mono<Void> postMono(ServerWebExchange exchange)
    {
        ...
    }

}
public class GraphQLWebsocketMessageConsumer implements Consumer<String>, WebSocketHandler
{

    private static final Logger logger = LoggerFactory.getLogger(GraphQLWebsocketMessageConsumer.class);

    private final ServerWebExchange swe;

    private final GraphQLObjectMapper objectMapper;

    private final GraphQLInvoker graphQLInvoker;

    private final GraphQLSpringInvocationInputFactory invocationInputFactory;

    private final Sinks.Many<String> publisher;

    public GraphQLWebsocketMessageConsumer(ServerWebExchange swe, GraphQLObjectMapper objectMapper,
            GraphQLInvoker graphQLInvoker, GraphQLSpringInvocationInputFactory invocationInputFactory)
    {
        ...
        publisher = Sinks.many().multicast().directBestEffort();
    }

    @Override
    public Mono<Void> handle(WebSocketSession webSocketSession)
    {
        Mono<Void> input = webSocketSession.receive().map(WebSocketMessage::getPayloadAsText).doOnNext(this).then();
        Mono<Void> sender = webSocketSession.send(publisher.asFlux().map(webSocketSession::textMessage));
        return Mono.zip(input, sender).then();
    }

    @Override
    public void accept(String body)
    {
        try
        {
            String query = extractQuery(body);
            if(query == null)
            {
                return;
            }
            GraphQLRequest request = objectMapper.readGraphQLRequest(query);
            GraphQLSingleInvocationInput invocationInput = invocationInputFactory.create(request, swe);
            Mono<ExecutionResult> executionResult = Mono.fromCompletionStage(graphQLInvoker.executeAsync(invocationInput));
            Mono<String> jsonResult = executionResult.map(objectMapper::serializeResultAsJson);
            jsonResult.subscribe(publisher::tryEmitNext);
        } catch (Exception e)
        {
            ...
        }
    }

    @SuppressWarnings("unchecked")
    private String extractQuery(final String query) throws Exception
    {
        Map<String, Object> map = (Map<String, Object>) objectMapper.getJacksonMapper().readValue(query, Map.class);
        ...
        return queryPart;
    }

    @Override
    public List<String> getSubProtocols()
    {
        logger.debug("getSubProtocols called");
        return Collections.singletonList("graphql-ws");
    }

}

Spring Boot application failed to start when using GraphQL Java Tools

copy iconCopydownload iconDownload
<properties>
    <kotlin.version>1.5.0</kotlin.version>
</properties>

GraphQL subscription with Jetty 10 embedded

copy iconCopydownload iconDownload
JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) ->
{
    // This lambda will be called at the appropriate place in the
    // ServletContext initialization phase where you can initialize
    // and configure  your websocket container.

    // Configure defaults for container
    wsContainer.setDefaultMaxTextMessageBufferSize(65535);

    // Add WebSocket endpoint to javax.websocket layer
    wsContainer.addEndpoint(
        ServerEndpointConfig.Builder.create(
            SubscriptionEndpoint.class, "/subscriptions")
            .configurator(new GraphQLWSEndpointConfigurer())
        .build());
});

Should multi-threading always be used in GrpahQL's DataFetcher?

copy iconCopydownload iconDownload
type Query {
 allPost: [Post!]
}

type Post {
  id: ID!
  tittle: String!
  postDetail: PostDetail!
  comments: [Comments!]
}

type PostDetail {
  id: ID!
  # This can be converted into enum
  postMediaType: String! 
  postUrl: String!
}

type Comment{
 id:ID!
 name: String!
 description: String!
}
{
  allPost{
    id
    tittle
    postDetail {
     id
     postMediaType
     postUrl
    }
    comments{
     id
     name
     description
    }
  }
}
-----------------------
type Query {
 allPost: [Post!]
}

type Post {
  id: ID!
  tittle: String!
  postDetail: PostDetail!
  comments: [Comments!]
}

type PostDetail {
  id: ID!
  # This can be converted into enum
  postMediaType: String! 
  postUrl: String!
}

type Comment{
 id:ID!
 name: String!
 description: String!
}
{
  allPost{
    id
    tittle
    postDetail {
     id
     postMediaType
     postUrl
    }
    comments{
     id
     name
     description
    }
  }
}

BigDecimal not present when resolving type

copy iconCopydownload iconDownload
<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphql-spring-boot-starter</artifactId>
  <version>5.0.2</version>
</dependency>
<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphql-java-tools</artifactId>
  <version>5.2.4</version>
</dependency>

<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphiql-spring-boot-starter</artifactId>
  <version>5.0.2</version>
</dependency>
type TemplateLineItemAction {
    type: String!
    quantity: BigDecimal
}
-----------------------
<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphql-spring-boot-starter</artifactId>
  <version>5.0.2</version>
</dependency>
<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphql-java-tools</artifactId>
  <version>5.2.4</version>
</dependency>

<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphiql-spring-boot-starter</artifactId>
  <version>5.0.2</version>
</dependency>
type TemplateLineItemAction {
    type: String!
    quantity: BigDecimal
}
-----------------------
@Component
public class BoaDataWiring implements RuntimeWiringBuilderCustomizer {
  private final NowService nowService;

  public BoaDataWiring(NowService nowService) {
    this.nowService = nowService;
  }

  @Override
  public void customize(RuntimeWiring.Builder builder) {
    /*
     * Declare the scalar here in the RuntimeWiring.Builder
     * Note there remains some ugly deprecation warning...
     *
     * "The is a non standard scalar and is difficult for clients 
     * (such as browser and mobile code) to cope with the exact 
     * semantics. These will be removed in the future version and 
     * moved to another library."
     */
    builder.scalar(Scalars.GraphQLBigDecimal); // <- This is what did it
    builder.type("Query", wiring ->
        wiring.dataFetcher("now", env -> nowService.now()));
  }
}

/**
 * RuntimeWiring provides access to the RuntimeWiring.Builder.
 */
@Component
public class RuntimeWiring implements RuntimeWiringConfigurer {
  private static final Logger LOG = LoggerFactory.getLogger(RuntimeWiring.class);

  @Override
  public void configure(graphql.schema.idl.RuntimeWiring.Builder builder) {
    LOG.trace("configure( builder: {} )", builder);
    builder.scalar(Scalars.GRAPHQL_DATE);
    builder.scalar(Scalars.GRAPHQL_BIG_DECIMAL);
  }
}
-----------------------
@Component
public class BoaDataWiring implements RuntimeWiringBuilderCustomizer {
  private final NowService nowService;

  public BoaDataWiring(NowService nowService) {
    this.nowService = nowService;
  }

  @Override
  public void customize(RuntimeWiring.Builder builder) {
    /*
     * Declare the scalar here in the RuntimeWiring.Builder
     * Note there remains some ugly deprecation warning...
     *
     * "The is a non standard scalar and is difficult for clients 
     * (such as browser and mobile code) to cope with the exact 
     * semantics. These will be removed in the future version and 
     * moved to another library."
     */
    builder.scalar(Scalars.GraphQLBigDecimal); // <- This is what did it
    builder.type("Query", wiring ->
        wiring.dataFetcher("now", env -> nowService.now()));
  }
}

/**
 * RuntimeWiring provides access to the RuntimeWiring.Builder.
 */
@Component
public class RuntimeWiring implements RuntimeWiringConfigurer {
  private static final Logger LOG = LoggerFactory.getLogger(RuntimeWiring.class);

  @Override
  public void configure(graphql.schema.idl.RuntimeWiring.Builder builder) {
    LOG.trace("configure( builder: {} )", builder);
    builder.scalar(Scalars.GRAPHQL_DATE);
    builder.scalar(Scalars.GRAPHQL_BIG_DECIMAL);
  }
}

Schema input type always &quot;LinkedHashMap cannot be cast...&quot;

copy iconCopydownload iconDownload
GraphQLQueryResolver
GraphQLMutationResolver
ObjectMapper objectMapper = new ObjectMapper();
            String input = objectMapper.writeValueAsString(env.getArgument("input"));
            final String arg = env.getArgument("input");
            return templateBomService.createTemplateLineItem(id, objectMapper.readValue(arg,TemplateLineItemInput.class));
-----------------------
GraphQLQueryResolver
GraphQLMutationResolver
ObjectMapper objectMapper = new ObjectMapper();
            String input = objectMapper.writeValueAsString(env.getArgument("input"));
            final String arg = env.getArgument("input");
            return templateBomService.createTemplateLineItem(id, objectMapper.readValue(arg,TemplateLineItemInput.class));

Spring Cloud Kubernetes: Timeout waiting for informers cache to be ready

copy iconCopydownload iconDownload
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: YOUR-NAME-SPACE
  name: namespace-reader
rules:
  - apiGroups: ["", "extensions", "apps"]
    resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
    verbs: ["get", "list", "watch"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-reader-binding
  namespace: YOUR-NAME-SPACE
subjects:
- kind: ServiceAccount
  name: default
  apiGroup: ""
roleRef:
  kind: Role
  name: namespace-reader
  apiGroup: ""
-----------------------
kubectl get secrets --namespace joaomlneto
kubectl get secret/default-token-..... --template='{{.data.namespace}}' --namespace joaomlneto
-----------------------
kubectl get secrets --namespace joaomlneto
kubectl get secret/default-token-..... --template='{{.data.namespace}}' --namespace joaomlneto

How to programmatically define a field of type yet-to-be fully defined in GraphQL-Java?

copy iconCopydownload iconDownload
GraphQLTypeReference.typeRef(typeName)
GraphQLNonNull.nonNull(typeRef)
-----------------------
GraphQLTypeReference.typeRef(typeName)
GraphQLNonNull.nonNull(typeRef)

How to solve a double bean conflict in Spring

copy iconCopydownload iconDownload
@Component
public class SampleBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
     // find the bean definition of the bean you need and try to:
     // - set "primary" on it
     String bdName = ... here put the name of the bean you want to fine-tune
     BeanDefinition beanDefinition =  beanFactory.getBeanDefinition(bdName);
     beanDefinition.setPrimary(true);
     // ... or ... 
     // - remove it altogether from the application context (bean factory)
     ((BeanDefinitionRegistry)beanFactory).removeBeanDefinition(bdName);

Community Discussions

Trending Discussions on graphql-java
  • How to handle custom GraphQL error such that it does not display the exception stack trace in Java
  • Spring Boot GraphQLQueryResolver won't run, runs on test project
  • graphql-spring-boot-starter Application with only websockets
  • Spring Boot application failed to start when using GraphQL Java Tools
  • GraphQL Input type declaration for Mutation
  • GraphQL subscription with Jetty 10 embedded
  • Should multi-threading always be used in GrpahQL's DataFetcher?
  • BigDecimal not present when resolving type
  • Schema input type always &quot;LinkedHashMap cannot be cast...&quot;
  • Gradle api transitive dependencies not working
Trending Discussions on graphql-java

QUESTION

How to handle custom GraphQL error such that it does not display the exception stack trace in Java

Asked 2022-Mar-24 at 08:19

I have created a simple GraphQL endpoint using Spring Boot and I am using DefaultGraphQLErrorHandler() to handle GraphQL errors.

However, when I throw a custom Exception from my application, the error response which GraphQL produces contains Exception stack trace which is giving away too much information. I want to prevent this.

{
"data": {
    "CommercialAsset": null
},
"errors": [
    {
        "message": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source",
        "path": [
            "CommercialAsset"
        ],
        "exception": {
            "cause": null,
            "stackTrace": [
                {
                    "classLoaderName": null,
                    "moduleName": null,
                    "moduleVersion": null,
                    "methodName": "getAssetById",
                    "fileName": "CommercialAssetDremioRepositoryImpl.java",
                    "lineNumber": 49,
                    "className": "com.dell.dremioclient.repository.impl.CommercialAssetDremioRepositoryImpl",
                    "nativeMethod": false
                },
                ...
                {
                    "classLoaderName": null,
                    "moduleName": "java.base",
                    "moduleVersion": "11.0.14",
                    "methodName": "run",
                    "fileName": "Thread.java",
                    "lineNumber": 834,
                    "className": "java.lang.Thread",
                    "nativeMethod": false
                }
            ],
            "message": "Asset not fround in Data source",
            "locations": null,
            "errorType": null,
            "path": null,
            "extensions": null,
            "suppressed": [],
            "localizedMessage": "Asset not fround in Data source"
        },
        "locations": [
            {
                "line": 2,
                "column": 5,
                "sourceName": null
            }
        ],
        "extensions": null,
        "errorType": "DataFetchingException"
    }
]

}

GraphQL dependency versions that I am using :

    <dependency>
       <groupId>com.graphql-java</groupId>
        <artifactId>graphql-spring-boot-starter</artifactId>
        <version>5.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.graphql-java</groupId>
        <artifactId>graphql-java-tools</artifactId>
        <version>5.2.4</version>
    </dependency>
    <dependency>
        <groupId>com.graphql-java</groupId>
        <artifactId>graphiql-spring-boot-starter</artifactId>
        <version>5.0.2</version>
    </dependency>

Is there any way I can do it using Custom error handler? Something like this -

public class CustomGraphqlErrorHandler implements GraphQLErrorHandler {

@Override
public List<GraphQLError> processErrors(List<GraphQLError> errors) {
    
    List<GraphQLError> errorList = new ArrayList<>();
    
    errors.stream()
            .forEach( e -> {
                if(this.isServerError(e)) {
                    GraphqlDremioClientException gexp = new GraphqlDremioClientException(e.getMessage());
                    gexp.setStackTrace(null); /* This causes failure Bad POST request: parsing failed
                                                 java.lang.NullPointerException: null
                                                 at java.base/java.lang.Throwable.setStackTrace(Throwable.java:865) */
                    errorList.add(gexp);
                } else {
                    errorList.add(e);
                }
            });
    
    return errorList;
}

private boolean isServerError(GraphQLError error) {
    return (error instanceof ExceptionWhileDataFetching || error instanceof Throwable);
}

@Override
public boolean errorsPresent(List<GraphQLError> errors) {
    return !CollectionUtils.isEmpty(errors);
}

}

ANSWER

Answered 2022-Mar-24 at 08:19

I wanted to prevent GraphQL to show stack trace in the error response. One simple solution to it was to add a custom GraphQL error handler to handle the exceptions thrown from my services. I then, created a custom Exception class which could enable or disable stack trace during construction.

Custom Exception class:

public class GraphqlDremioClientException extends RuntimeException implements GraphQLError {

    private static final long serialVersionUID = 1L;
    
    private final String message;
    
    private boolean writeStacktrace = false;

    @Override
    public String getMessage() {
        return message;
    }
    /* other constructors */
        
    public GraphqlDremioClientException(String message, boolean writeStacktrace) {
        super(message, null, false, writeStacktrace);
        this.writeStacktrace = writeStacktrace;
        this.message = message;
    }
    
    public GraphqlDremioClientException(String message, Exception ex) {
        super();
        this.message = message;
    }

    @Override
    public List<SourceLocation> getLocations() {
        return null;
    }

    @Override
    public ErrorType getErrorType() {
        return null;
    }       
}

Custome GraphQL error handler:

@Slf4j
@Component
public class CustomGraphqlErrorHandler implements GraphQLErrorHandler {

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> list) {
        return list.stream().map(this::getNested).collect(Collectors.toList());
    }
    
    private GraphQLError getNested(GraphQLError error) {
        log.error(error.getMessage(), error);
        
        if (error instanceof ExceptionWhileDataFetching) {
            ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
            if (exceptionError.getException() instanceof GraphQLError) {
                return new GraphqlDremioClientException(exceptionError.getMessage(), false);
            }
        }
        return error;
    }
}

The error response now:

{
    "data": {
        "CommercialAsset": null
    },
    "errors": [
        {
            "cause": null,
            "stackTrace": [],
            "message": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source",
            "writeStacktrace": false,
            "locations": null,
            "errorType": null,
            "path": null,
            "extensions": null,
            "suppressed": [],
            "localizedMessage": "Exception while fetching data (/CommercialAsset) : Asset not fround in Data source"
        }
    ]
}

Source https://stackoverflow.com/questions/71493628

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install graphql-java

You can download it from GitHub, Maven.
You can use graphql-java like any standard Java library. Please include the the jar files in your classpath. You can also use any IDE and you can run and debug the graphql-java component as you would do with any other Java program. Best practice is to use a build tool that supports dependency management such as Maven or Gradle. For Maven installation, please refer maven.apache.org. For Gradle installation, please refer gradle.org .

Support

We have a tutorial for beginners: Getting started with GraphQL Java and Spring Boot. For details how to use graphql-java please look at the documentation: https://www.graphql-java.com/documentation/getting-started. Please take a look at our list of releases if you want to learn more about new releases and the changelog.

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Explore Related Topics

Share this Page

share link
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.