使用 webclient 在 spring 引导中调用 graphql 突变 API

using webclient to call the grapql mutation API in spring boot

我在 spring 引导中调用 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 层。

您必须在 post 请求中将 query 和正文作为变量发送,如图所示 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<String,Object> 来形成 graphQL 请求体,但是你也可以使用 queryvariables[= 的属性创建相应的 POJO 类 18=]