Lab 13b: Calling External REST APIs
Description¶
This is Part 2 of the "external API call" lab.
To support different currencies for the coffee order's total price, we'll call to an external currency conversion API using Spring's RestTemplate
. This will be done in two steps:
-
Create a stub service that returns a hard-coded value, to make sure it's integrated properly.
-
A real,
RestTemplate
-based implementation that calls out to the API service.
g. Real Currency Conversion Service¶
Now you will implement the CurrencyService
so it will call out to the remote API. Refer to the example below as needed for later sections.
The Weather API Example
This is the code and response DTO from the Weather example:
Learning from examples is great, but don't just blindly copy-n-paste...
// instantiate a RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// create a Template URL for the API
String weatherUrl = "https://basic-weather.herokuapp.com/api/zip/{zip}";
// put the variables in a Map
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("zip", "94404");
// call out to the remote API and get back a DTO
WeatherResponse response =
restTemplate.getForObject(weatherUrl,
WeatherResponse.class,
uriVariables);
This is the DTO that's used above:
public class WeatherResponse {
private String location;
private String updated;
private Float temp;
private String condition;
// getters and setters go here
}
h. DTO for Response¶
Create a DTO ConvertedCurrency
that represents the returned JSON. The properties must match the JSON key names below, i.e., it will have 2 properties: the currency string, and the converted amount as a BigDecimal
.
The JSON returned from this API looks like this:
{
"currency": "GBP",
"converted": 71.00
}
i. Using RestTemplate¶
You'll call out to the remote API like this:
https://jitterted-currency-conversion.herokuapp.com/convert?from=USD&to=GBP&amount=100
-
Create a new class,
HttpCurrencyConversionService
in thecom.welltestedlearning.coffeekiosk.adapter.out.currency
package.This class will implement the
CurrencyConversionService
interface, using the remote API to do the conversion. -
Since you'll now have two
@Service
s implementating the same interface, you'll need to use the Spring Profile feature to select among the implementations:- Add
@Profile("dev")
as an annotation to theStubCurrencyConversionService
class - Add
@Profile("prod")
as an annotation to theHttpCurrencyConversionService
class - In the
application.properties
file, add a new line:spring.profiles.active=prod
- Add
-
In the
convertToBritishPound
method, create a URI Template string for the remote API:- The base part of the URI is
http://jitterted-currency-conversion.herokuapp.com/convert
- There are three query parameters:
from
- the source currency, e.g.,USD
to
- the converted currency, e.g.,GBP
amount
- the amount to convert, e.g., 10
Example
To convert 100 in USD to GBP, the URI would look like this:
http://jitterted-currency-conversion.herokuapp.com/convert?from=USD&to=GBP&amount=100
Think about what parts of the string need to become replaceable template variables. A URI Template Variable looks like this:
{amount}
. - The base part of the URI is
-
Instantiate a
RestTemplate
and use thegetForObject()
method, passing in these 3 parameters:- The URI template string from above
ConvertedCurrency.class
- The query parameters in the map
-
Calling
getForObject()
returns an instance ofConvertedCurrency
, so take theconverted
amount (which is aBigDecimal
) and return it as anint
.
j. Try It Out¶
Start the application and try it with the browser, curl
, or Postman, both with and without the query parameter of ?currency=gbp
:
What happens if you change the profile in the application.properties
file to dev
?