【问题标题】:Make a POST call to GraphQL API programmatically using Java使用 Java 以编程方式对 GraphQL API 进行 POST 调用
【发布时间】:2020-03-22 02:47:35
【问题描述】:

我必须将带有一些标头和 graphQL 变量的查询作为对 java 中的 GraphQL API 的 POST 调用发送。我还必须在查询中发送一些标头和身份验证参数。现在,我正在 POSTMAN 中进行手动调用,但我想以编程方式执行此操作。你们能帮我从哪里开始吗?我的查询和变量如下

query sampleQuery($param: SampleQueryParams!, $pagingParam: PagingParams) {
    sampleLookup(params: $param, pagingParams: $pagingParam) {
        ID
        name1
        name2 
    }
}

而我的 GraphQL 变量如下:

{"param": {"id": 58763897}, "pagingParam": {"pageNumber": 0, "pageSize": 10 } }

我不知道从哪里开始。各位大神能帮忙吗

【问题讨论】:

  • 我对 GraphQL Java 生态系统了解不多,但第一步可能是查看 HTTP 客户端库。任何可以创建 POST 请求的 HTTP 客户端都应该可以做到这一点。

标签: java graphql graphql-java


【解决方案1】:

下面是一个典型的用于 java 后端的 graphql 端点

这里有2个基本流程

1 http 请求的端点,可以将 graghql 查询处理为字符串和查询输入变量的 map / json 表示形式

2 用于整理和返回数据的后端的 graphql 接线

后端通常会有一个看起来像这样 (1) 的端点

   public Map<String, Object> graphqlGET(@RequestParam("query") String query,
                                      @RequestParam(value = "operationName", required = false) String operationName,
                                      @RequestParam("variables") String variablesJson) throws IOException {...

请注意,我们有 3 个输入
一个查询字符串,
查询变量的字符串通常为 json
一个可选的“操作名称”

一旦我们解析了这些输入参数,我们通常会将它们发送到 graphql 实现以进行查询

可能看起来像这样 (1)

  private Map<String, Object> executeGraphqlQuery(String operationName,
                                                String query, Map<String, Object> variables) {
    ExecutionInput executionInput = ExecutionInput.newExecutionInput()
            .query(query)
            .variables(variables)
            .operationName(operationName)
            .build();

    return graphql.execute(executionInput).toSpecification();
}

这里的 graphql 对象具有返回数据的所有接线

所以一个解决方案就是将格式正确的输入参数发布到后端
我经常使用 android 和一个适用于旧 android 版本的 http 客户端,因此 kotlin 中的 post 请求可能看起来像这样一个非常简单的示例

    val client = HttpClients.createDefault()
    val httpPost = HttpPost(url)
    val postParameters = ArrayList<NameValuePair>()
    postParameters.add(BasicNameValuePair("query", "query as string"))
    postParameters.add(BasicNameValuePair("variables", "variables json string"))
    httpPost.entity = UrlEncodedFormEntity(postParameters, Charset.defaultCharset())
    val response = client.execute(httpPost)
    val ret =  EntityUtils.toString(response.getEntity())

请注意http post的实现取决于后端java实现的设置方式

对于基本的 http 客户端和 post setup 这里有很多很好的例子
How to use parameters with HttpPost

可能相关

graphql 允许一个内省流程,该流程发布有关实现支持的查询结构的详细信息 更多信息在这里

https://graphql.org/learn/introspection/

[1]https://github.com/graphql-java/graphql-java-examples

【讨论】:

  • 这有帮助。非常感谢您的详细回答!
【解决方案2】:

我建议将graphql-java-codegen 插件用于这些目的。

它提供了基于架构生成类的可能性,您可以提供给任何 HTTP 客户端。

例如,GraphQL 服务器有以下架构,我们要执行productById 查询:

type Query {
    productById(id: ID!): Product
}

type Product {
    id: ID!
    title: String!
    price: BigDecimal!
}

graphql-java-codegen 将生成执行查询所需的所有类:

// preparing request
ProductByIdQueryRequest request = new ProductByIdQueryRequest();
request.setId(productId);
// preparing response projection (which fields to expect in the response)
ProductResponseProjection responseProjection = new ProductResponseProjection()
        .id()
        .title()
        .price();

// preparing a composite graphql request
GraphQLRequest graphQLRequest = new GraphQLRequest(request, responseProjection);

// performing a request with the constructed object
ProductByIdQueryResponse responseBody = restTemplate.exchange(URI.create("https://product-service:8080/graphql"),
        HttpMethod.POST,
        new HttpEntity<>(graphQLRequest.toHttpJsonBody()),
        ProductByIdQueryResponse.class).getBody();
// Fetching a serialized object from response
Product product = responseBody.productById();

更多示例可以在 GitHub 上找到:https://github.com/kobylynskyi/graphql-java-codegen#supported-plugins

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    相关资源
    最近更新 更多