Home > OS >  Multiple graphQL client endpoints in spring boot
Multiple graphQL client endpoints in spring boot

Time:10-27

In my project I need to fetch data from multiple graphql endpoints. I defined one in my application.properties file like so: graphql.client.url=https://api.foo.com/graphql-1 and fetching data in code:

public Foo getFooByid(String id) throws Exception {
    final GraphQLRequest request =
        GraphQLRequest.builder()
            .query(orgByIdQuery)
            .variables(Map.of("id", id))
            .build();

    final GraphQLResponse response = graphQLWebClient.post(request).block();
    response.validateNoErrors();

    return response.get("Foo", Foo.class);

  }

So there is some magic that gets client url from application.properties file. Now, how can I have second client url https://api.foo.com/graphql-2 defined and used in my code? Dependency for gql:

    <dependency>
      <groupId>com.graphql-java-kickstart</groupId>
      <artifactId>graphql-webclient-spring-boot-starter</artifactId>
      <version>1.0.0</version>
    </dependency>

CodePudding user response:

Once you have defined all the URLs you want (with a @Value tied to your properties file), you should create a HttpGraphQlClient Bean, which you can then mutate for each request:

@Bean
HttpGraphQlClient graphQlClient(){
    return HttpGraphQlClient.builder()
            .url(firstUrl)
            .build();
}

Inside your other Component you make your first request...

graphQlClient
            .documentName(orgByIdQuery)
            .retrieve("org") 
            ... //etc

Then you can modify it as many times as you want

graphQlClient
            .mutate()
            .header("Authorization","Basic anVsaW86YHIJ0ZUJBMjAyMg==") //many different customizations are allowed
            .url(anotherUrl)
            .build()
            .documentName(orgByIdQuery)
            .retrieve("org") 
            ... //etc

Hope it helps!

CodePudding user response:

Lib seems to allow configuration via props for 1 client. Other clients seems has to be created programmatically.

Then either placed into spring context or used internally in class. Please see WebClientAutoConfiguration which provide WebClient.Builder and customizers for produced WebClient. It may be possible to reuse WebClient.Builder, which is already in spring context and set another baseUrl, but create new builder and configure it seems as better approach. Possible example:

@Component
class GqlService(
    objectMapper: ObjectMapper,
    customizerProvider: ObjectProvider<WebClientCustomizer>,
    @Value("\$graphql.client2.url") baseUrl: String
) {
    private val secondGqlClient: GraphQLWebClient
    
    init {
        val builder = WebClient.builder()
        customizerProvider.orderedStream().forEach { customizer -> customizer.customize(builder) }
        builder.baseUrl(baseUrl)
        secondGqlClient = GraphQLWebClient.newInstance(builder.build(), objectMapper)
    }
}
  • Related