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

bhmjp9jg  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(182)

背景

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

提问

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

我现在的实现

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
            }
        }
    }
}

用法

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

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

13z8s7eq

13z8s7eq1#

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

相关问题