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