Enhancing Flexibility: Implementing Multi-API Support in ConversorDeMonedas
Introduction
In our currency converter project, ConversorDeMonedas, we recently identified a need for greater reliability and redundancy when fetching exchange rates. Relying on a single source of truth for financial data can create a single point of failure; if the API goes down, the entire application stops working.
The Challenge
Previously, the application was tightly coupled to one specific provider. This made it difficult to:
- Switch providers during service outages.
- Compare data accuracy between different financial services.
- Maintain the application without hard-coding specific endpoint logic.
The Solution
We introduced a strategy pattern to decouple the service selection logic from the application workflow. This allows the system to choose between different providers, such as ExchangeRate or CoinGecko, at runtime.
public interface ExchangeProvider {
double getRate(String base, String target);
}
public class CurrencyService {
private ExchangeProvider provider;
public void setProvider(ExchangeProvider provider) {
this.provider = provider;
}
public double convert(double amount, String base, String target) {
return amount * provider.getRate(base, target);
}
}
This approach acts like a power strip with multiple outlets; no matter which appliance (API provider) you plug in, as long as it fits the plug shape (the ExchangeProvider interface), the system functions correctly without needing internal rewiring.
Key Decisions
- Interface Abstraction: By defining an
ExchangeProviderinterface, we ensure that adding future APIs requires minimal changes to the core business logic. - Dependency Injection: We use a setter method to swap implementations, allowing for easy testing and runtime configuration switching.
- Decoupling: The business logic no longer cares how the data is fetched, only that it adheres to the contract.
Results
- Improved system resilience by enabling quick failover between API providers.
- Cleaner, more modular code structure that is easier to maintain and test.
- Increased developer velocity when adding support for new external financial services.
Lessons Learned
Building for modularity from the start pays off. When dealing with external dependencies, always build an abstraction layer to act as a buffer between your code and the unpredictable nature of third-party APIs.
Generated with Gitvlg.com