Skip to content

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:

  1. Create a stub service that returns a hard-coded value, to make sure it's integrated properly.

  2. 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
  1. Create a new class, HttpCurrencyConversionService in the com.welltestedlearning.coffeekiosk.adapter.out.currency package.

    This class will implement the CurrencyConversionService interface, using the remote API to do the conversion.

  2. Since you'll now have two @Services 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 the StubCurrencyConversionService class
    • Add @Profile("prod") as an annotation to the HttpCurrencyConversionService class
    • In the application.properties file, add a new line: spring.profiles.active=prod
  3. 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:
      1. from - the source currency, e.g., USD
      2. to - the converted currency, e.g., GBP
      3. 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}.

  4. Instantiate a RestTemplate and use the getForObject() method, passing in these 3 parameters:

    1. The URI template string from above
    2. ConvertedCurrency.class
    3. The query parameters in the map
  5. Calling getForObject() returns an instance of ConvertedCurrency, so take the converted amount (which is a BigDecimal) and return it as an int.

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?