Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 62 additions & 21 deletions documentation/modules/ROOT/pages/08_rest-client.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,71 @@

A typical scenario in a Microservices architecture is the remote invocation of remote REST HTTP endpoints. Quarkus provides a typed REST client that follows the https://github.com/eclipse/microprofile-rest-client[MicroProfile REST Client, window=_blank] specification.

Let's create a REST client that accesses https://swapi.dev[window=_blank] to get additional information about Movies. The endpoint we're interested in is this one:
Let's create a REST client that accesses https://swapi.info[window=_blank] to get additional information about Movies. The endpoint we're interested in is this one:

* `api/films/?search=\{title\}`, which returns specific info about the given movie.
* `api/films/\{id\}`, which returns specific info about the given movie.

[.console-output]
[source, json]
----
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"title": "The Empire Strikes Back",
"episode_id": 5,
"opening_crawl": "It is a dark time for the\r\nRebellion. Although the Death\r\nStar has been destroyed,\r\nImperial troops have driven the\r\nRebel forces from their hidden\r\nbase and pursued them across\r\nthe galaxy.\r\n\r\nEvading the dreaded Imperial\r\nStarfleet, a group of freedom\r\nfighters led by Luke Skywalker\r\nhas established a new secret\r\nbase on the remote ice world\r\nof Hoth.\r\n\r\nThe evil lord Darth Vader,\r\nobsessed with finding young\r\nSkywalker, has dispatched\r\nthousands of remote probes into\r\nthe far reaches of space....",
"director": "Irvin Kershner",
"producer": "Gary Kurtz, Rick McCallum",
"release_date": "1980-05-17",
"created": "2014-12-12T11:26:24.656000Z",
"edited": "2014-12-15T13:07:53.386000Z",
"url": "https://swapi.dev/api/films/2/"
}
]
"title": "A New Hope",
"episode_id": 4,
"opening_crawl": "It is a period of civil war.\r\nRebel spaceships, striking\r\nfrom a hidden base, have won\r\ntheir first victory against\r\nthe evil Galactic Empire.\r\n\r\nDuring the battle, Rebel\r\nspies managed to steal secret\r\nplans to the Empire's\r\nultimate weapon, the DEATH\r\nSTAR, an armored space\r\nstation with enough power\r\nto destroy an entire planet.\r\n\r\nPursued by the Empire's\r\nsinister agents, Princess\r\nLeia races home aboard her\r\nstarship, custodian of the\r\nstolen plans that can save her\r\npeople and restore\r\nfreedom to the galaxy....",
"director": "George Lucas",
"producer": "Gary Kurtz, Rick McCallum",
"release_date": "1977-05-25",
"characters": [
"https://swapi.info/api/people/1",
"https://swapi.info/api/people/2",
"https://swapi.info/api/people/3",
"https://swapi.info/api/people/4",
"https://swapi.info/api/people/5",
"https://swapi.info/api/people/6",
"https://swapi.info/api/people/7",
"https://swapi.info/api/people/8",
"https://swapi.info/api/people/9",
"https://swapi.info/api/people/10",
"https://swapi.info/api/people/12",
"https://swapi.info/api/people/13",
"https://swapi.info/api/people/14",
"https://swapi.info/api/people/15",
"https://swapi.info/api/people/16",
"https://swapi.info/api/people/18",
"https://swapi.info/api/people/19",
"https://swapi.info/api/people/81"
],
"planets": [
"https://swapi.info/api/planets/1",
"https://swapi.info/api/planets/2",
"https://swapi.info/api/planets/3"
],
"starships": [
"https://swapi.info/api/starships/2",
"https://swapi.info/api/starships/3",
"https://swapi.info/api/starships/5",
"https://swapi.info/api/starships/9",
"https://swapi.info/api/starships/10",
"https://swapi.info/api/starships/11",
"https://swapi.info/api/starships/12",
"https://swapi.info/api/starships/13"
],
"vehicles": [
"https://swapi.info/api/vehicles/4",
"https://swapi.info/api/vehicles/6",
"https://swapi.info/api/vehicles/7",
"https://swapi.info/api/vehicles/8"
],
"species": [
"https://swapi.info/api/species/1",
"https://swapi.info/api/species/2",
"https://swapi.info/api/species/3",
"https://swapi.info/api/species/4",
"https://swapi.info/api/species/5"
],
"created": "2014-12-10T14:23:31.880000Z",
"edited": "2014-12-20T19:49:45.256000Z",
"url": "https://swapi.info/api/films/1"
}
----

Expand Down Expand Up @@ -363,10 +404,10 @@ curl -w '\n' localhost:8080/movie?year=1980
{
"title": "The Empire Strikes Back",
"releaseDate": "1980-05-17",
"episodeId": 0,
"producer": "Gary Kurtz, Rick McCallum",
"episode_id": 5,
"opening_crawl": "It is a dark time for the\r\nRebellion. Although the Death\r\nStar has been destroyed,\r\nImperial troops have driven the\r\nRebel forces from their hidden\r\nbase and pursued them across\r\nthe galaxy.\r\n\r\nEvading the dreaded Imperial\r\nStarfleet, a group of freedom\r\nfighters led by Luke Skywalker\r\nhas established a new secret\r\nbase on the remote ice world\r\nof Hoth.\r\n\r\nThe evil lord Darth Vader,\r\nobsessed with finding young\r\nSkywalker, has dispatched\r\nthousands of remote probes into\r\nthe far reaches of space....",
"director": "Irvin Kershner",
"opening_crawl": "It is a dark time for the\r\nRebellion. Although the Death\r\nStar has been destroyed,\r\nImperial troops have driven the\r\nRebel forces from their hidden\r\nbase and pursued them across\r\nthe galaxy.\r\n\r\nEvading the dreaded Imperial\r\nStarfleet, a group of freedom\r\nfighters led by Luke Skywalker\r\nhas established a new secret\r\nbase on the remote ice world\r\nof Hoth.\r\n\r\nThe evil lord Darth Vader,\r\nobsessed with finding young\r\nSkywalker, has dispatched\r\nthousands of remote probes into\r\nthe far reaches of space...."
"producer": "Gary Kurtz, Rick McCallum"
}
]
----
55 changes: 24 additions & 31 deletions documentation/modules/ROOT/pages/09_fault-tolerance.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import jakarta.ws.rs.core.MediaType;

import com.redhat.developers.Swapi.Results;

@Path("/api")
@RegisterRestClient
public interface SwapiService {
@GET
Expand Down Expand Up @@ -115,35 +114,24 @@ Change the `SwapiService` Java interface in `src/main/java` in the `com.redhat.d
----
package com.redhat.developers;

import java.util.List;

import org.eclipse.microprofile.faulttolerance.ExecutionContext;
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.faulttolerance.FallbackHandler;
import org.eclipse.microprofile.faulttolerance.Retry;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.faulttolerance.*;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

import com.redhat.developers.Swapi.Results;

@Path("/api")
@RegisterRestClient
public interface SwapiService {

@GET
@Path("/films/")
@Path("/films/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Retry(maxRetries = 3, delay = 2000)
@Timeout(value = 2000L)
@Fallback(SwapiFallback.class)
public Swapi getFilmById(@PathParam("id") String id);

public static class SwapiFallback implements FallbackHandler<Swapi> {

private static final Swapi EMPTY_SWAPI = new Swapi(List.of(new Results(0,"","","")));
private static final Swapi EMPTY_SWAPI = new Swapi("",0,"","","");
@Override
public Swapi handle(ExecutionContext context) {
return EMPTY_SWAPI;
Expand Down Expand Up @@ -198,30 +186,35 @@ Change the `SwapiService` Java interface in `src/main/java` in the `com.redhat.d
----
package com.redhat.developers;

import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
import org.eclipse.microprofile.faulttolerance.Retry;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.faulttolerance.*;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

@Path("/api")
@RegisterRestClient
public interface SwapiService {
@GET
@Path("/films/")
@Path("/films/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Retry(maxRetries = 3, delay = 2000)
@Timeout(value = 2000L)
@Fallback(SwapiFallback.class)
@CircuitBreaker(
requestVolumeThreshold=4,
failureRatio=0.75,
delay=5000
requestVolumeThreshold = 4,
failureRatio = .5,
delay = 5000L,
successThreshold = 2
)
public Swapi getFilmById(@PathParam("id") String id);

public static class SwapiFallback implements FallbackHandler<Swapi> {

private static final Swapi EMPTY_SWAPI = new Swapi("",0,"","","");
@Override
public Swapi handle(ExecutionContext context) {
return EMPTY_SWAPI;
}

}
}

----
Expand Down