graphql-java-kickstart/graphql-spring-webclient

Customized result mapping and error handling

1096kc opened this issue · 9 comments

Hi team, I have a use case where one of my downstream services is switching from a Rest endpoint to a GraphQL endpoint. I'm exploring to see if I can use graphql-spring-webclient to consume the new GraphQL endpoint and found a couple of issues:

  1. Currently, I'm using Spring WebClient to consume the Rest endpoint, we have our own customized result mapping and error handling logic based on the ClientResponse instance that's returned from the webclient. I'm wondering in graphql-spring-webclient, is it possible to avoid directly mapping the response to GraphQLResponse so that I can reuse the result mapping and error handling logic I have?
return webClient.post().uri(props.getPath())
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .header(OPERATION, OPERATION_NAME)
                .body(Mono.just(createRequestBody(key)), CustomizedRequest.class)
                .exchange()
                .flatMap(result -> processResponse(result, CustomizedResult.class))
                .transformDeferred(CircuitBreakerOperator.of(circuitBreakerRegistry.circuitBreaker(GATEWAY_NAME)))
                .block();
  1. Instead of pre-define the query string in a resource file, are we planning to provide a mechanism to dynamically generate the query?
  1. The GraphQLResponse basically is just a DTO that's in line with the GraphQL specification. Do you mean the expected response from that GraphQL API is not in line with the specification and you want to handle that differently? Not sure I really get the use case here.

  2. What is your definition of "dynamically generating the query"? How would this work?

Thank you so much for your reply.

  1. Currently, the implementation of post method in GraphQL-Spring-WebClient did the resulting mapping using objectMapper by default. I'm wondering if we can provide another post method that returns a GraphQLResponse instance so that we can apply our own resulting mapping logic with error handling logic based on that GraphQLResponse.

  2. We serve as an orchestration service that provides GraphQL endpoint, some of our downstream services are Rest endpoint and some are GraphQL endpoint. By dynamically generating the query, I mean that we would like to have the ability to dynamically generate GraphQL queries to our GraphQl downstream services based on what's been queried on our GraphQL endpoint. Do you have any ideas on that?

  1. Can you give a concrete example, because I don't have a clear picture of what you're trying to do here.

  2. Again something concrete. So you mean you want to just pass a String which represents the query? Or do you mean an Object that represents the query which is serialized by Jackson?

  1. Sorry I don't have a concrete example here, In general I'm talking about the result mapping and error handling part, currently in GraphQL-Spring-WebClient, if any error happens, a GraphQLErrorsException will be thrown with a list of GraphQLError. We have to catch thatGraphQLErrorsException and rethrow a customized exception if we want to have customized error handling logic. I'm just wondering instead of doing that, is it possible to just return a GraphQLResponse so that I can apply my own result mapping and error handling logic easier?

  2. Let's say I'm a GraphQL service provide named X, this is my schema.

Person{
   firstName
   lastName
   birthDay
   departmentNumber
   address
   .....
}

These three fields firstName, lastName, birthDay came from a downstream GraphQL service named A. And the other two fields come from another downstream Rest endpoint named B.
If a consumer sends this query to the service X

Person{
firstName
LastName
}

I want to query Service A with only these two fields instead of querying all three fields. Because in reality, Service X can have more than 100 fields that came from Service A. If a consumer queries service X with only two fields. I don't want to issue a query to service A with the full schema. So I'm wondering if we can have a mapping mechanism that can automatically generate query against service A based on what's been queried in Service X?

  1. This already makes it clearer. I missed the fact it was throwing an exception already. Thought it was just returning that GraphQLResponse as is.

  2. This webclient knows nothing about its usage, e.g. being part of an orchestrator. Your GraphQL resolver somehow needs to determine the actual query and then use that to construct the query you want to send using this webclient. Which means instead of a resource name you should probably just manually construct the query string then and pass that. If you see another approach then please clarify.

Also: could you split up this issue in two separate feature requests please.

Thank you for your reply! I will create two separate feature requests and close this one.

I don't see a new feature request for that second issue we discussed here. Is that still relevant or not anymore?

I don't see a new feature request for that second issue we discussed here. Is that still relevant or not anymore?

I think that's not relevant to graphql-spring-WebClient. I will try to build the query dynamically in my resolver, thanks.