How can spring-boot application easily get data from external GraphQL service?

How can spring-boot application easily get data from external GraphQL service?


1

Background

My spring-boot-3 application need to get data from external GraphQL API. There I can/need fetch data by 4 different queries. I want to find some generic GraphQL Client with default GraphQL exceptions handling and default response conversion to objects.


Question

Is there any simple way to call GraphQL API? Any dependency or client for that?


Implementation that I have now

GraphQLQueryLoader.class

@Slf4j
@RequiredArgsConstructor
@Component
public class GraphQLQueryLoader {

  private final ResourceLoader resourceLoader;

  /**
   * Query file should be in
   * <code>/resources/graphql/{fileName}.graphql</code>
   * */
  public String loadQuery(final String queryName) {
    try {
      final var location = "classpath:graphql/" + queryName + ".graphql";
      final var path = resourceLoader.getResource(location).getFile().getPath();
      return Files.readString(Paths.get(path));
    } catch (final Exception e) {
      log.error(String.format("Could not load GraphQL query (%s).", queryName), e);
      throw new GraphQLQueryException();
    }
  }

}

GraphQLClient.class

@Slf4j
@RequiredArgsConstructor
public class GraphQLClient {

  private static final Duration TIMEOUT = Duration.ofSeconds(30);

  private final WebClient webClient;
  private final GraphQLQueryLoader graphQLQueryLoader;

  public GraphQLResponse getByQueryName(final String query) {
    final var query = graphQLQueryLoader.loadQuery(query);
    return webClient.post()
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .body(BodyInserters.fromValue(query))
                    .retrieve()
                    .onStatus(HttpStatusCode::is4xxClientError, handleClientError())
                    .onStatus(HttpStatusCode::is5xxServerError, handleServerError())
                    .bodyToMono(GraphQLResponse.class)
                    .block(TIMEOUT);
  }

  private Function<ClientResponse, Mono<? extends Throwable>> handleClientError() {
    return response -> response.bodyToMono(String.class)
                               .flatMap(body -> {
                                 log.warn("Client error with body: {}", body);
                                 return Mono.error(new HttpClientErrorException(response.statusCode(), "Client error"));
                               });
  }

  private Function<ClientResponse, Mono<? extends Throwable>> handleServerError() {
    return response -> response.bodyToMono(String.class)
                               .flatMap(body -> {
                                 log.warn("Server error with body: {}", body);
                                 return Mono.error(new HttpServerErrorException(response.statusCode(), "Server error"));
                               });
  }

}

GraphQLResponse.class

public record GraphQLResponse(Object data) {}

resources/graphql/my-query.graphql

query myQuery() {
    myQuery(id: '123') {
        myCollection {
            items {
                title
                body
                action
            }
        }
    }
}

Usage

final var response = client.getByQueryName("my-query");

Is there any other easier way to get data from GraphQL API? Internet suggests only how to create GraphQL service, but nothing about any GraphQL client…

2

  • 1

    In my opinion, your current implementation is good and there is no easier way to achieve this.

    – user699848

    3 hours ago

  • If you are already using Spring for GraphQL that also provides a client (see docs.spring.io/spring-graphql/reference/client.html).

    – M. Deinum

    3 hours ago

1 Answer
1


0

graphql-java-kickstart, this library provides a convenient way to work with GraphQL in Java. You can refer to the official documentation for more details: graphql-java-kickstart.

1

  • That's not what I am searching for. Documentation says: graphql-spring-boot-starter : turns your Spring Boot application into a GraphQL Server…

    – Dumbo

    58 mins ago



Leave a Reply

Your email address will not be published. Required fields are marked *