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)
}
}
