【问题标题】:using webclient to call the grapql mutation API in spring boot在 Spring Boot 中使用 webclient 调用 graphql 变异 API
【发布时间】:2022-01-24 20:18:05
【问题描述】:

我在 Spring Boot 中调用 graphQL 变异 API 时卡住了。让我解释一下我的场景,我有两个微服务,一个是 AuditConsumeService,它使用来自 activeMQ 的消息,另一个是 GraphQL 层,它只是从消费服务中获取数据并将其放入数据库中。当我尝试使用 graphql 游乐场或邮递员推送数据时,一切都很好。如何从 AuditConsumeService 推送数据。在 AuditConsumeService 中,我试图将突变 API 作为字符串发送。负责将其发送到 graphQL 层的方法是

public Mono<String> sendLogsToGraphQL(String logs){
        return webClient
                .post()
                .uri("http://localhost:8080/logs/createEventLog")
                .bodyValue(logs)
                .retrieve()
                .bodyToMono(String.class);
    }  

注意:我也尝试将数据作为对象传递,但没有用。 String logs 将由 activeMQ 提供给它。我发送的数据是;

{
    "hasError": false,
    "message": "Hello There",
    "sender": "Ali Ahmad",
    "payload": {
        "type": "String",
        "title": "Topoic",
        "description": "This is the demo description of the activemqq"
    },
    "serviceInfo":{
        "version": "v1",
        "date": "2021-05-18T08:44:17.8237608+05:00",
        "serverStatus": "UP",
        "serviceName": "IdentityService"
    }
}

变异会是这样的;

mutation($eventLog:EventLogInput){
  createEventLog(eventLog: $eventLog){
    hasError
    message
    payload{
      title,
      description
    }
  }
}

$eventLog 的 json 正文为;

{
  "eventLog": {
    "hasError": false,
    "message": "Hello There",
    "sender": "Ali Ahmad",
    "payload": {
        "type": "String",
        "title": "Topoic",
        "description": "This is the demo description of the activemqq"
    },
    "serviceInfo":{
        "version": "v1",
        "date": "2021-05-18T08:44:17.8237608+05:00",
        "serverStatus": "UP",
        "serviceName": "IdentityService"
    }
}
}

编辑 遵循以下答案,将消费者服务更新为;

@Component
public class Consumer {
    @Autowired
    private AuditService auditService;

    private final String MUTATION_QUERY = "mutation($eventLog: EventLogInput){\n" +
            "createEventLog(eventLog: $eventLog){\n" +
            "hasError\n" +
            "}\n" +
            "}";

    @JmsListener(destination = "Audit.queue")
    public void consumeLogs(String logs) {
        Gson gson = new Gson();
        Object jsonObject = gson.fromJson(logs, Object.class);
        Map<String, Object> graphQlBody = new HashMap<>();
        graphQlBody.put("query", MUTATION_QUERY);
        graphQlBody.put("variables", "{eventLog: " + jsonObject+ "}");
        auditService.sendLogsToGraphQL(graphQlBody);
    }
}

现在 `sendLogsToGraphQL' 将变为。

public void sendLogsToGraphQL(Map<String, String> logs) {
        log.info("Logs: {} ", logs);
        Mono<String> stringMono = webClient
                .post()
                .uri("http://localhost:8080/graphql")
                .bodyValue(BodyInserters.fromValue(logs))
                .retrieve()
                .bodyToMono(String.class);
        log.info("StringMono: {}", stringMono);
        return stringMono;
    }

数据没有通过指定的 url 发送到 graphql 层。

【问题讨论】:

    标签: java spring-boot graphql webclient


    【解决方案1】:

    您必须将query 和正文作为post 请求中的变量发送,如here 所示

    graphQlBody = { "query" : mutation_query, "variables" : { "eventLog" : event_log_json } }
    

    然后在webClient 你可以通过多种方式发送正文

    public Mono<String> sendLogsToGraphQL(Map<String,Object> body){
        return webClient
                .post()
                .uri("http://localhost:8080/logs/createEventLog")
                .bodyValue(BodyInserters.fromValue(body))
                .retrieve()
                .bodyToMono(String.class);
    }  
    

    这里我只是展示了使用Map&lt;String,Object&gt; 来形成graphQL 请求体,但是您也可以使用queryvariables 的属性创建相应的POJO 类

    【讨论】:

    • 感谢您的回复。您将graphQLBody 定义为地图,但我很惊讶您在哪里使用它,因为我在sendLogsToGraphQL 方法中看不到它的存在。
    • graphQLBody 需要作为 webclient 发布请求的主体传递,因此在您的情况下,您需要调用 sendLogsToGraphQL 传递该主体
    • graphQlBody 中的变量 mutation_query 也是一个简单的字符串,其中包含像 String mutation_query = "mutation" 这样的查询。同样event_log_json 只包含我的 json 字符串。
    • 我更新了我的问题,添加了 ConsumeService 方法,该方法将 json 作为来自 activeMQ 的字符串,请看一下,因为我遵循了你的答案,但它不起作用。
    • 最后我解决了,我没有发送地图,而是简单地发送字符串为; final String query = "{\"query\": " + MUTATION_QUERY + ", \"variables\": {\"eventLog\": " + logs + "}}"; ,并将其作为参数传递给 RestTemplate,现在它可以工作了。
    猜你喜欢
    • 2018-10-04
    • 2021-12-23
    • 2020-07-25
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 2021-04-05
    • 2021-09-13
    • 2020-03-22
    相关资源
    最近更新 更多