- How do I integrate this with Laravel’s HTTP client instead of symfony/http-client?
- Replace `symfony/http-client` with Laravel’s native `HttpClient` in your service container binding. Exchanger’s `ExchangeRateService` accepts any PSR-18 client, so bind it like this: `app()->bind(ExchangeRateService::class, fn() => new ExchangeRateService(new HttpClient(), new CacheManager()))`. Laravel’s `HttpClient` is PSR-18 compliant out of the box.
- Can I use Laravel’s cache (e.g., Redis, database) with Exchanger’s PSR-16 caching?
- Yes, but you’ll need a PSR-16 adapter. Install `spatie/laravel-cache-psr16` and configure it in `config/cache.php`. Then pass the adapter to Exchanger: `new ExchangeRateService(..., new Psr16CacheAdapter(Cache::store('redis')))`. This bridges Laravel’s cache drivers to Exchanger’s caching layer.
- What’s the best way to handle API keys for commercial providers in Laravel?
- Store keys in Laravel’s `.env` file (e.g., `FASTFOREX_API_KEY`) and inject them via the service container. For security, use Laravel’s `config()` helper or environment variables directly in your provider configuration. Avoid hardcoding keys in your codebase. Example: `new FastforexProvider(config('services.fastforex.key'))`.
- How do I set up a fallback chain between multiple providers?
- Use the `ChainExchangeRateService` class. Pass an array of providers in priority order: `new ChainExchangeRateService([new FastforexProvider($key), new EcbProvider(), new ExchangerateHostProvider()])`. If the first provider fails, it automatically tries the next. You can also customize error handling per provider in the chain.
- Does Exchanger support cryptocurrency exchange rates?
- Limited support. Only providers like `coinlayer` and `cryptonator` include crypto pairs. Most public providers (e.g., ECB, national banks) focus on fiat currencies. For crypto-heavy applications, prioritize these providers in your chain or consider a dedicated crypto API like `nomics` or `coinbase`.
- How do I test Exchanger in Laravel with mocked provider responses?
- Use PHPUnit’s mock builder to stub the `ExchangeRateService` interface. Example: `$mock = $this->createMock(ExchangeRateService::class); $mock->method('getRate')->willReturn(1.2);`. Bind the mock in your test’s service container: `$app->instance(ExchangeRateService::class, $mock)`. For historical rates, mock the `getHistoricalRate` method similarly.
- What Laravel versions are officially supported?
- Exchanger is framework-agnostic but works with Laravel 9+ (PHP 8.2+). Tested dependencies like `symfony/http-client` and `nyholm/psr7` are compatible with Laravel’s latest LTS versions. For older Laravel versions, ensure your PHP version meets Exchanger’s 8.2+ requirement and manually resolve PSR-18/PSR-16 dependencies.
- How do I cache exchange rates globally vs. per-query in Laravel?
- For global caching, use a single PSR-16 cache instance with keys like `exchange_rate:{base}:{quote}:{date}`. For per-query caching, pass a query-specific cache key to `getRate()` or `getHistoricalRate()`. Example: `$service->getRate('EUR', 'USD', now(), 'eur_usd_daily_cache')`. Laravel’s cache tags can further refine invalidation.
- Are there performance considerations for chaining multiple providers?
- Yes. Chaining increases latency, especially if providers have rate limits or slow responses. Prioritize faster providers (e.g., `fastforex`) first in the chain. Use PSR-16 caching with short TTLs (e.g., 5 minutes) for volatile rates. Monitor provider response times with Laravel’s logging or tools like Blackfire.
- What’s the difference between Exchanger and the higher-level Swap library?
- Swap is a **currency conversion library** built on top of Exchanger, offering features like automatic rounding, currency formatting, and multi-step conversions (e.g., USD → EUR → GBP). Use Exchanger when you need **raw exchange rates** with fine-grained control over providers, caching, or historical data. Swap is ideal for end-user-facing applications.