Skip to main content

Overview

The Currency Converter integrates with ExchangeRate-API to retrieve real-time currency conversion rates. The integration is implemented in the ConsultaMoneda service class using Java’s modern HTTP client.

ConsultaMoneda Service Class

Class Definition

Package: lad.com.alura.conversormoneda.modelos
public class ConsultaMoneda {
    public double obtenerTasa(String monedaBase, 
                             String monedaObjetivo, 
                             double cantidad) {
        // Implementation
    }
}

obtenerTasa() Method

The core method that performs currency conversion by calling the ExchangeRate-API.
monedaBase
String
required
The source currency code in ISO 4217 format (e.g., “USD”, “EUR”, “ARS”)
monedaObjetivo
String
required
The target currency code in ISO 4217 format (e.g., “ARS”, “BRL”, “COP”)
cantidad
double
required
The amount to convert from the base currency
returns
double
The converted amount in the target currency, or 0 if an error occurs

Complete Implementation

public class ConsultaMoneda {

    // Instance method (not static) - follows OOP principles
    public double obtenerTasa(String monedaBase, String monedaObjetivo, double cantidad) {
        try {
            // Create HTTP client
            HttpClient cliente = HttpClient.newHttpClient();
            
            // Build API URL
            String url = "https://v6.exchangerate-api.com/v6/9ba310889b4d07769a662fc0/pair/" 
                + monedaBase + "/" + monedaObjetivo + "/" + cantidad;

            // Build HTTP request
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .GET()
                    .build();

            // Send request and receive response
            HttpResponse<String> respuesta = cliente.send(request, 
                HttpResponse.BodyHandlers.ofString());

            // Parse JSON response
            JsonElement elemento = JsonParser.parseString(respuesta.body());
            JsonObject objectRoot = elemento.getAsJsonObject();

            // Extract conversion result
            return objectRoot.get("conversion_result").getAsDouble();

        } catch (Exception e) {
            System.out.println("Error al conectar con la API: " + e.getMessage());
            return 0;
        }
    }
}

API Endpoint Structure

Endpoint Format

https://v6.exchangerate-api.com/v6/{api_key}/pair/{base}/{target}/{amount}
api_key
string
required
Your ExchangeRate-API key. The application uses a hardcoded key: 9ba310889b4d07769a662fc0
base
string
required
Three-letter ISO 4217 currency code for the base currency
target
string
required
Three-letter ISO 4217 currency code for the target currency
amount
number
required
The amount in the base currency to convert

Example API Calls

GET https://v6.exchangerate-api.com/v6/9ba310889b4d07769a662fc0/pair/USD/ARS/100
Converts 100 US Dollars to Argentine Pesos

HttpClient Usage

The application uses Java 11’s modern HttpClient API for HTTP communication.

HTTP Client Creation

HttpClient cliente = HttpClient.newHttpClient();
HttpClient.newHttpClient() creates a new client with default configuration. For production applications, consider reusing a single client instance for better performance.

Building HTTP Requests

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(url))  // Set the target URI
        .GET()                  // Set HTTP method to GET
        .build();               // Build the request

Builder Pattern

The HttpRequest.Builder uses the builder pattern for fluent, readable request configuration.

Sending Requests

HttpResponse<String> respuesta = cliente.send(
    request, 
    HttpResponse.BodyHandlers.ofString()
);
request
HttpRequest
The HTTP request to send
bodyHandler
BodyHandler<String>
Specifies how to handle the response body. ofString() converts the response to a String

JSON Parsing with Gson

The application uses the Gson library to parse JSON responses from the API.

API Response Format

{
  "result": "success",
  "documentation": "https://www.exchangerate-api.com/docs",
  "terms_of_use": "https://www.exchangerate-api.com/terms",
  "time_last_update_unix": 1585267200,
  "time_last_update_utc": "Fri, 27 Mar 2020 00:00:00 +0000",
  "time_next_update_unix": 1585353700,
  "time_next_update_utc": "Sat, 28 Mar 2020 00:00:00 +0000",
  "base_code": "USD",
  "target_code": "ARS",
  "conversion_rate": 63.2341,
  "conversion_result": 6323.41
}

Parsing Implementation

1

Parse JSON String

JsonElement elemento = JsonParser.parseString(respuesta.body());
Converts the raw JSON string into a JsonElement object
2

Convert to JsonObject

JsonObject objectRoot = elemento.getAsJsonObject();
Casts the element to a JsonObject for property access
3

Extract Conversion Result

return objectRoot.get("conversion_result").getAsDouble();
Retrieves the conversion_result field and converts it to a double

Key JSON Fields

result

Status of the API call: "success" or "error"

base_code

The base currency code requested

target_code

The target currency code requested

conversion_result

The final converted amount - this is what the application returns

Error Handling

The implementation includes comprehensive error handling for network and parsing issues.

Try-Catch Block

try {
    // HTTP request and JSON parsing logic
} catch (Exception e) {
    System.out.println("Error al conectar con la API: " + e.getMessage());
    return 0;
}

Common Error Scenarios

Exception Type: IOExceptionOccurs when:
  • No internet connection
  • DNS resolution fails
  • Firewall blocks the request
Handling: Returns 0 and prints error message
Exception Type: JsonParseExceptionOccurs when:
  • API returns malformed JSON
  • Response format changes
  • Server error response
Handling: Returns 0 and prints error message
Exception Type: NullPointerExceptionOccurs when:
  • conversion_result field is missing
  • API returns error response
Handling: Returns 0 and prints error message
Exception Type: InterruptedExceptionOccurs when:
  • Request thread is interrupted
  • Request times out
Handling: Returns 0 and prints error message
Production Consideration: Returning 0 on error could be confused with a legitimate conversion result. Consider:
  • Using Optional<Double> to represent success/failure
  • Throwing custom exceptions (e.g., ApiConnectionException)
  • Logging errors to a file instead of just console output

Dependencies

The API integration requires the following Java dependencies:
<dependencies>
    <!-- Gson for JSON parsing -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.10.1</version>
    </dependency>
</dependencies>
The java.net.http.HttpClient is part of the Java 11+ standard library and requires no external dependencies.

API Rate Limits

ExchangeRate-API has the following rate limits:

Free Plan

1,500 requests per month

Response Time

Typically under 100ms
For production applications with higher traffic, consider:
  • Caching conversion rates for a few minutes
  • Implementing retry logic with exponential backoff
  • Upgrading to a paid API plan

Best Practices

The API key is currently hardcoded. For production:
// Use environment variables
String apiKey = System.getenv("EXCHANGE_RATE_API_KEY");
String url = "https://v6.exchangerate-api.com/v6/" + apiKey + "/pair/...";
Or use a properties file:
Properties props = new Properties();
props.load(new FileInputStream("config.properties"));
String apiKey = props.getProperty("api.key");
Create a single HttpClient instance and reuse it:
public class ConsultaMoneda {
    private final HttpClient cliente = HttpClient.newHttpClient();
    
    public double obtenerTasa(String base, String target, double amount) {
        // Use this.cliente instead of creating new one
    }
}
Prevent hanging requests:
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .GET()
        .timeout(Duration.ofSeconds(10))
        .build();
Validate currency codes before making API calls:
private static final Set<String> VALID_CURRENCIES = 
    Set.of("USD", "ARS", "BRL", "COP", "EUR", "GBP");

if (!VALID_CURRENCIES.contains(monedaBase)) {
    throw new IllegalArgumentException("Invalid base currency");
}

Build docs developers (and LLMs) love