Getting Data from API Json Reactive, , WebClient, SpringBoot 2.6, JUnit5
Source API https://swapi.dev/
http://swapi.dev/api/people?search=noexist
{ "count": 0, "next": null, "previous": null, "results": [] }
http://swapi.dev/api/people?search=luke
{ "count": 1, "next": null, "previous": null, "results": [ { "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "https://swapi.dev/api/planets/1/", "films": [ "https://swapi.dev/api/films/1/", "https://swapi.dev/api/films/2/", "https://swapi.dev/api/films/3/", "https://swapi.dev/api/films/6/" ], "species": [], "vehicles": [ "https://swapi.dev/api/vehicles/14/", "https://swapi.dev/api/vehicles/30/" ], "starships": [ "https://swapi.dev/api/starships/12/", "https://swapi.dev/api/starships/22/" ], "created": "2014-12-09T13:50:51.644000Z", "edited": "2014-12-20T21:17:56.891000Z", "url": "https://swapi.dev/api/people/1/" } ] }
@RestController
public class ClientExample {
private WebClient swapi = WebClient.create("https://swapi.dev/api/");
@GetMapping(value = "/api/starwars/findCharactersTrace/{characterName}")
public void findCharacter(@PathVariable String characterName){
Mono<Map> mapMono = swapi.get()
.uri("/people/?search={charName}", characterName)
.retrieve()
.bodyToMono(Map.class);
mapMono.subscribe(map -> {
map.keySet().forEach( k -> {
System.out.println(k + " " + map.get(k).toString());
});
});
}
When http://swapi.dev/api/people?search=noexist
Output:
count 0
When http://swapi.dev/api/people?search=luke
Output:
count 1
@GetMapping(value = "/api/starwars/findCharactersTrace/{characterName}")
public void findCharacter(@PathVariable String characterName){
Mono<Map> mapMono = swapi.get()
.uri("/people/?search={charName}", characterName)
.retrieve()
.bodyToMono(Map.class);
mapMono.subscribe(map -> {
System.out.println( map.get("results") );
});
}
When http://swapi.dev/api/people?search=noexist
Output:
[]
When http://localhost:8080/api/starwars/findCharactersTrace/luke
Output:
[{name=Luke Skywalker, height=172, mass=77, hair_color=blond, skin_color=fair, eye_color=blue, birth_year=19BBY, gender=male, homeworld=https://swapi.dev/api/planets/1/, films=[https://swapi.dev/api/films/1/, https://swapi.dev/api/films/2/, https://swapi.dev/api/films/3/, https://swapi.dev/api/films/6/], species=[], vehicles=[https://swapi.dev/api/vehicles/14/, https://swapi.dev/api/vehicles/30/], starships=[https://swapi.dev/api/starships/12/, https://swapi.dev/api/starships/22/], created=2014-12-09T13:50:51.644000Z, edited=2014-12-20T21:17:56.891000Z, url=https://swapi.dev/api/people/1/}]
@GetMapping(value = "/api/starwars/findCharactersTrace/{characterName}")
public void findCharacter(@PathVariable String characterName){
Mono<List<Map>> results = swapi.get()
.uri("/people/?search={charName}", characterName)
.retrieve()
.bodyToMono(Map.class)
.flatMap(map -> Mono.just((List<Map>) map.get("results")));
results.subscribe(maps -> maps.forEach(System.out::println));
}
flatMap returns a Mono<List<Map>> of the contents of key "results".
When http://localhost:8080/api/starwars/findCharactersTrace/luke
Output:
{name=Luke Skywalker, height=172, mass=77, hair_color=blond, skin_color=fair, eye_color=blue, birth_year=19BBY, gender=male, homeworld=https://swapi.dev/api/planets/1/, films=[https://swapi.dev/api/films/1/, https://swapi.dev/api/films/2/, https://swapi.dev/api/films/3/, https://swapi.dev/api/films/6/], species=[], vehicles=[https://swapi.dev/api/vehicles/14/, https://swapi.dev/api/vehicles/30/], starships=[https://swapi.dev/api/starships/12/, https://swapi.dev/api/starships/22/], created=2014-12-09T13:50:51.644000Z, edited=2014-12-20T21:17:56.891000Z, url=https://swapi.dev/api/people/1/}
@GetMapping(value = "/api/starwars/findCharactersTrace/{characterName}")
public void findCharacter(@PathVariable String characterName){
Flux<Map> results = swapi.get()
.uri("/people/?search={charName}", characterName)
.retrieve()
.bodyToMono(Map.class)
.flatMapMany(map -> Flux.fromIterable((List<Map>) map.get("results")));
results.subscribe(map -> map.forEach((k, v) -> System.out.println(k.toString() + ": " + v.toString())));
}
flatMapMany returns a Flux<Map> of the contents of key "results".
When http://localhost:8080/api/starwars/findCharactersTrace/luke
Output:
name: Luke Skywalker
height: 172
mass: 77
hair_color: blond
skin_color: fair
eye_color: blue
birth_year: 19BBY
gender: male
homeworld: https://swapi.dev/api/planets/1/
films: [https://swapi.dev/api/films/1/, https://swapi.dev/api/films/2/, https://swapi.dev/api/films/3/, https://swapi.dev/api/films/6/]
species: []
vehicles: [https://swapi.dev/api/vehicles/14/, https://swapi.dev/api/vehicles/30/]
starships: [https://swapi.dev/api/starships/12/, https://swapi.dev/api/starships/22/]
created: 2014-12-09T13:50:51.644000Z
edited: 2014-12-20T21:17:56.891000Z
url: https://swapi.dev/api/people/1/
@GetMapping(value = "/api/starwars/getCharacterTrace/{characterId}")
public void getCharacterTrace(@PathVariable int characterId){
Mono<Map> mapMono = swapi.get()
.uri("/people/{id}", characterId)
.retrieve()
.bodyToMono(Map.class);
mapMono.subscribe(map -> { map.forEach((k, v) -> System.out.println(k + ": " + v));
});
}
http://swapi.dev/api/people/1
{ "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "https://swapi.dev/api/planets/1/", "films": [ "https://swapi.dev/api/films/1/", "https://swapi.dev/api/films/2/", "https://swapi.dev/api/films/3/", "https://swapi.dev/api/films/6/" ], "species": [], "vehicles": [ "https://swapi.dev/api/vehicles/14/", "https://swapi.dev/api/vehicles/30/" ], "starships": [ "https://swapi.dev/api/starships/12/", "https://swapi.dev/api/starships/22/" ], "created": "2014-12-09T13:50:51.644000Z", "edited": "2014-12-20T21:17:56.891000Z", "url": "https://swapi.dev/api/people/1/" }
@GetMapping(value = "/api/starwars/getCharacterTrace/{characterId}")
public void getCharacterTrace(@PathVariable int characterId){
Mono<Map> mapMono = swapi.get()
.uri("/people/{id}", characterId)
.retrieve()
.bodyToMono(Map.class);
mapMono.subscribe(map -> { map.forEach((k, v) -> System.out.println(k + ": " + v));
});
}
When http://localhost:8080/api/starwars/getCharacterTrace/1
Output:
name: Luke Skywalker
height: 172
mass: 77
hair_color: blond
skin_color: fair
eye_color: blue
birth_year: 19BBY
gender: male
homeworld: https://swapi.dev/api/planets/1/
films: [https://swapi.dev/api/films/1/, https://swapi.dev/api/films/2/, https://swapi.dev/api/films/3/, https://swapi.dev/api/films/6/]
species: []
vehicles: [https://swapi.dev/api/vehicles/14/, https://swapi.dev/api/vehicles/30/]
starships: [https://swapi.dev/api/starships/12/, https://swapi.dev/api/starships/22/]
created: 2014-12-09T13:50:51.644000Z
edited: 2014-12-20T21:17:56.891000Z
url: https://swapi.dev/api/people/1/
fetchMovieTitles
@GetMapping(value = "/api/starwars/charInMoviesByNameTrace")
public void charInMoviesByNameTrace(@RequestParam String name) {
Flux<Map> characters = findCharacters(name);
characters.subscribe(map ->
map.forEach((k,v) -> System.out.println(k + ": " + v)
)
);
}
Output:
name: Luke Skywalker
height: 172
mass: 77
hair_color: blond
skin_color: fair
eye_color: blue
birth_year: 19BBY
gender: male
homeworld: https://swapi.dev/api/planets/1/
films: [https://swapi.dev/api/films/1/, https://swapi.dev/api/films/2/, https://swapi.dev/api/films/3/, https://swapi.dev/api/films/6/]
species: []
vehicles: [https://swapi.dev/api/vehicles/14/, https://swapi.dev/api/vehicles/30/]
starships: [https://swapi.dev/api/starships/12/, https://swapi.dev/api/starships/22/]
created: 2014-12-09T13:50:51.644000Z
edited: 2014-12-20T21:17:56.891000Z
url: https://swapi.dev/api/people/1/
This json is the input to the method fetchMovieTitles( json)
@GetMapping(value = "/api/starwars/charInMoviesByNameTrace")
public void charInMoviesByNameTrace(@RequestParam String name) {
Flux<String> characters = findCharacters(name)
.flatMap(json -> fetchMovieTitles(json));
characters.subscribe(System.out::println);
}
Output:
A New Hope
The Empire Strikes Back
Return of the Jedi
Revenge of the Sith
@GetMapping(value = "/api/starwars/charInMoviesByNameTrace")
public void charInMoviesByNameTrace(@RequestParam String name) {
Flux<String> characters = findCharacters(name)
.flatMapSequential(json -> fetchMovieTitles(json));
characters.subscribe(System.out::println);
}
Output:
A New Hope
The Empire Strikes Back
Return of the Jedi
Revenge of the Sith
@GetMapping(value = "/api/starwars/charInMoviesByNameTrace")
public void charInMoviesByNameTrace(@RequestParam String name) {
Flux<String> characters = findCharacters(name)
.flatMapSequential(json -> fetchMovieTitles(json)
.map(s -> s + "- add this to each -")
.startWith("= StartWith this - character " + json.get("name"))
.concatWith(Mono.just("ConcatWith this =")));
characters.subscribe(System.out::println);
}
Output:
= StartWith this - character Luke Skywalker
A New Hope- add this to each -
The Empire Strikes Back- add this to each -
Return of the Jedi- add this to each -
Revenge of the Sith- add this to each -
ConcatWith this =
But what happens in fetchMovieTitles( json), it receives a json with the data of the respective character, and in the key films wich is an array of uri that has the link to the movie titles.
private Flux<String> fetchMovieTitles(Map characterJson) {
if (characterJson.containsKey("films")) {
@SuppressWarnings("unchecked")
Iterable<String> movieUris = (Iterable<String>) characterJson.get("films");
return Flux.fromIterable(movieUris)
.concatMap(url -> swapi.get().uri(url)
.retrieve()
.bodyToMono(Map.class)
.map(map -> String.valueOf(map.get("title")))
);
}
else {
return Flux.error(new IllegalArgumentException("passed Map does not represent a character"));
}
}
eot
No hay comentarios:
Publicar un comentario