spring boot应用程序如何从外部GraphQL服务轻松获取数据?

bhmjp9jg  于 2024-01-05  发布在  Spring
关注(0)|答案(1)|浏览(275)

背景

我的spring-boot-3应用程序需要从外部GraphQL API获取数据。在那里我可以/需要通过4个不同的查询获取数据。我想找到一些通用的GraphQL客户端,具有默认的GraphQL异常处理和默认的响应转换为对象。

提问

有没有简单的方法来调用GraphQL API?有没有依赖项或客户端?

我现在的实现

GraphQLQueryLoader.class

  1. @Slf4j
  2. @RequiredArgsConstructor
  3. @Component
  4. public class GraphQLQueryLoader {
  5. private final ResourceLoader resourceLoader;
  6. /**
  7. * Query file should be in
  8. * <code>/resources/graphql/{fileName}.graphql</code>
  9. * */
  10. public String loadQuery(final String queryName) {
  11. try {
  12. final var location = "classpath:graphql/" + queryName + ".graphql";
  13. final var path = resourceLoader.getResource(location).getFile().getPath();
  14. return Files.readString(Paths.get(path));
  15. } catch (final Exception e) {
  16. log.error(String.format("Could not load GraphQL query (%s).", queryName), e);
  17. throw new GraphQLQueryException();
  18. }
  19. }
  20. }

字符串

GraphQLClient.class

  1. @Slf4j
  2. @RequiredArgsConstructor
  3. public class GraphQLClient {
  4. private static final Duration TIMEOUT = Duration.ofSeconds(30);
  5. private final WebClient webClient;
  6. private final GraphQLQueryLoader graphQLQueryLoader;
  7. public GraphQLResponse getByQueryName(final String query) {
  8. final var query = graphQLQueryLoader.loadQuery(query);
  9. return webClient.post()
  10. .contentType(MediaType.APPLICATION_JSON)
  11. .accept(MediaType.APPLICATION_JSON)
  12. .body(BodyInserters.fromValue(query))
  13. .retrieve()
  14. .onStatus(HttpStatusCode::is4xxClientError, handleClientError())
  15. .onStatus(HttpStatusCode::is5xxServerError, handleServerError())
  16. .bodyToMono(GraphQLResponse.class)
  17. .block(TIMEOUT);
  18. }
  19. private Function<ClientResponse, Mono<? extends Throwable>> handleClientError() {
  20. return response -> response.bodyToMono(String.class)
  21. .flatMap(body -> {
  22. log.warn("Client error with body: {}", body);
  23. return Mono.error(new HttpClientErrorException(response.statusCode(), "Client error"));
  24. });
  25. }
  26. private Function<ClientResponse, Mono<? extends Throwable>> handleServerError() {
  27. return response -> response.bodyToMono(String.class)
  28. .flatMap(body -> {
  29. log.warn("Server error with body: {}", body);
  30. return Mono.error(new HttpServerErrorException(response.statusCode(), "Server error"));
  31. });
  32. }
  33. }

GraphQLResponse.class

  1. public record GraphQLResponse(Object data) {}

resources/graphql/my-query.graphql

  1. query myQuery() {
  2. myQuery(id: '123') {
  3. myCollection {
  4. items {
  5. title
  6. body
  7. action
  8. }
  9. }
  10. }
  11. }

用法

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

还有其他更简单的方法从GraphQL API获取数据吗?互联网只建议如何创建GraphQL服务,但没有任何关于GraphQL客户端的建议。

13z8s7eq

13z8s7eq1#

graphql-java-kickstart,这个库提供了一种在Java中使用GraphQL的方便方法。您可以参考官方文档了解更多详细信息:graphql-java-kickstart

相关问题