I am slightly confused to get the proper response when the user tries to use two rest endpoints with WebClient. I want to use it as asynchronous and non-blocking in the code.
I am returning the Flux from the controller. The code details are as below:
The Controller Class method looks like this:
@RequestMapping(method = RequestMethod.GET, path = "/v1/repos/{userName}", produces = "application/json")
public ResponseEntity<Flux<GithubRepo>> getUserReposDetails(
@PathVariable(name="userName",required = true) String userName) throws Exception{
return new ResponseEntity<>(this.getGitRepos(userName), HttpStatus.OK);
}
It is calling getGitRepos method. The method details are as below:
private Flux<GithubRepo> getGitRepos(String userName) {
return webClient.get().uri("/users/{userName}/repos",userName).
exchangeToFlux(clientResponse -> clientResponse.bodyToFlux(GithubRepo.class)).map(github->{
github.setBranch(webClient.get()
.uri("/repos/{userName}/{branchName}/branches",userName,github.getBranch())
.retrieve().bodyToFlux(Branch.class).collectList());
return github;
});
}
And WebClient is:
WebClient webClient = WebClient.builder().baseUrl("https://api.github.com").
defaultHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.github.v3+json").build();
The GitHub and Branch Classes are below:
@Data
public class GithubRepo {
private String name;
private String ownerLogin;
private Mono<List<Branch>> branch;
@JsonProperty("owner")
private void unpackNested(Map<String,String> commit) {
this.ownerLogin = commit.get("login");
}
}
@Data
public class Branch {
private String name;
private Boolean protected;
}
I am getting the JSON response as:
[
{
"name": "HelloWorld",
"ownerLogin": "test",
"branch": {
"scanAvailable": true
}
},
{
"name": "rokehan",
"ownerLogin": "test",
"branch": {
"scanAvailable": true
}
},
{
"name": "sNews",
"ownerLogin": "test",
"branch": {
"scanAvailable": true
}
},
{
"name": "Test--01",
"ownerLogin": "test",
"branch": {
"scanAvailable": true
}
}
]
I want to get the response as:
[
{
"name": "HelloWorld",
"ownerLogin": "test",
"branch": [
{
"name": "asd",
"protected": false
},
{
"name": "master",
"protected": false
}
]
},
{
"name": "rokehan",
"ownerLogin": "test",
"branch": [
{
"name": "master",
"protected": false
}
]
},
{
"name": "sNews",
"ownerLogin": "test",
"branch": []
},
{
"name": "Test--01",
"ownerLogin": "test",
"branch": [
{
"name": "master",
"protected": false
}
]
}
]
Please help me to resolve this problem.
Mono<List<Branch>
when you construct yourGithubRepo
you need to have aList<Branch>
instead. – VinelandflatMap
aftercollectList
and create your object there. Me personally i would have one object that matches the github api, and another object that you return to the calling client. So that the apis can evolve independantly. – Vineland