miércoles, 16 de marzo de 2022

Getting Data from API Json Reactive, WebClient, SpringBoot 2.6, JUnit5

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