1

I'm trying to build a camel route to consume the message from ActiveMQ and extract some JSON fields and send the extracted payload to graphql server. I followed graphql component documentation, however, I was unable to figure out how to get the variable values dynamically from the exchange.

# bookByIdQuery.graphql
query($id : String!) {
  book(id :$id) {
    id
    name
  }
}

@BindToRegistry("bookByIdQueryVariables")
public JsonObject bookByIdQueryVariables() {
    JsonObject variables = new JsonObject();
    variables.put("id", "book-1");
    return variables;
}

from("direct:start")
    .to("graphql://http://example.com/graphql?queryFile=bookByIdQuery.graphql&variables=#bookByIdQueryVariables")

In the above example, I want to get the variable value from the exchange. I mean book-1 I need to get from exchange. For that, I made the method to accept the exchange as a parameter, however it does not replace the values in the query. I tried to debug and seen the exchange as null and bookByIdQueryVariables bean is found in context. Seems like there is no converter to convert the bookByIdQueryVariables type to a JSON object. Please suggest if there is a problem in graphql query or variable bean. Any help is appreciated

Chin Huang
  • 12,912
  • 4
  • 46
  • 47

1 Answers1

0

You can lookup bookByIdQueryVariables object in registry, which can be obtained from camel context, and replace it with exchange message body (or whatever you want):

from("direct:start")
    .process(exchange -> {
        String body = exchange.getIn().getBody(String.class);
        Registry registry = exchange.getContext().getRegistry();
        JsonObject variables = registry.lookupByNameAndType("bookByIdQueryVariables", JsonObject.class);
        variables.put("id", body);
    })
    .to("graphql://http://example.com/graphql?queryFile=bookByIdQuery.graphql&variables=#bookByIdQueryVariables")

EDIT:

as Chin Huang mentioned, depending on the context, it might be unsafe to follow this approach, because we're mutating shared value in the registry. In context of synchronous routes it should be pretty safe, but if it's intended to use in multithreaded/concurrent environment then it most likely won't be a good solution.

t3h_b0t
  • 120
  • 1
  • 5
  • If you modify the `bookByIdQueryVariables` object in the registry, then would concurrently executing exchanges try to put different values into the `id` variable? If the registry has one `bookByIdQueryVariables` object, then a GraphQL step might send a wrong `id` value. In my opinion, the Camel GraphQL component should be enhanced to dynamically read these variables from the message body or headers. – Chin Huang Dec 15 '20 at 17:55
  • @ChinHuang agreed, I've edited my answer. – t3h_b0t Dec 15 '20 at 19:49
  • @ChinHuang. You are right. Now I'm facing situation, Do you have any solution in case of multithreading? – javalearner Jan 08 '21 at 18:41