Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Exchangeratehost Bundle Laravel Package

benjaminmal/exchangeratehost-bundle

Unofficial Symfony bundle for the free exchangerate.host API. PSR-7/17/18 compatible so you can choose your HTTP client and message factories, with built-in Symfony Cache support for faster, fewer requests. PHP 8.1+ and Symfony 6.2+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require benjaminmal/exchangeratehost-bundle nyholm/psr7 symfony/http-client
    

    Add to config/app.php under providers:

    Benjaminmal\ExchangeRateHostBundle\ExchangeRateHostBundle::class,
    
  2. Configure API Key: Add to .env:

    EXCHANGERATEHOST_API_KEY=your_api_key_here
    
  3. First Use Case: Inject the client into a service and fetch latest rates:

    use Benjaminmal\ExchangeRateHostBundle\Client\ExchangeRateHostClientInterface;
    
    class CurrencyService {
        public function __construct(private ExchangeRateHostClientInterface $client) {}
    
        public function getUsdRate() {
            $rates = $this->client->getLatestRates(['symbols' => ['USD']]);
            return $rates['USD'] ?? 0;
        }
    }
    

Implementation Patterns

Core Workflows

  1. Currency Conversion:

    $converted = $this->client->convertCurrency(
        fromCurrency: 'EUR',
        toCurrency: 'USD',
        amount: 100.00
    );
    
  2. Historical Data:

    $historical = $this->client->getHistoricalRates(
        date: new DateTimeImmutable('-1 day')
    );
    
  3. Time-Series Analysis:

    $series = $this->client->getTimeSeriesRates(
        startDate: new DateTimeImmutable('-30 days'),
        endDate: new DateTimeImmutable('-1 day')
    );
    

Integration Tips

  • Dependency Injection: Prefer constructor injection for ExchangeRateHostClientInterface over facades for testability.

  • Cache Layer: Extend the default cache pool for granular control:

    # config/cache.php
    pools:
        exchangeratehost.cache:
            adapter: cache.adapter.redis
            provider: 'redis://localhost'
    
  • Error Handling: Wrap API calls in try-catch blocks:

    try {
        $rates = $this->client->getLatestRates();
    } catch (\RuntimeException $e) {
        // Log or retry logic
    }
    
  • Batch Processing: Use getSupportedCurrencies() to pre-fetch all symbols before bulk operations.


Gotchas and Tips

Pitfalls

  1. Cache Invalidation:

    • ExchangeRate.host updates rates daily at 00:05 GMT. Schedule a cron job to clear caches:
      6 0 * * * php artisan cache:clear exchangeratehost.cache
      
    • Timezone Note: Cron uses server time; adjust for your timezone (e.g., 6 0 * * * for UTC+1).
  2. Rate Limits:

    • The free tier has 1,000 requests/day. Cache aggressively to avoid hitting limits:
      exchangerate_host:
          cache:
              enabled: true
              pools:
                  latest_rates: 'exchangeratehost.cache'
      
  3. Floating-Point Precision:

    • Use places option in LatestRatesOption to control decimal places (default: 4):
      $rates = $this->client->getLatestRates([
          'places' => 2,
      ]);
      
  4. Type Safety:

    • The convertCurrency() method returns int|float. Explicitly cast results:
      $amount = (float) $this->client->convertCurrency(...);
      

Debugging

  • Enable API Tracing: Decorate the client with TraceableExchangeRateHostClient (built-in decorator) to log requests:

    $this->client->withTrace(function ($request, $response) {
        \Log::debug("API Call: {$request->getUri()}", [
            'response' => $response->getBody()->getContents()
        ]);
    });
    
  • Validate API Key: Test connectivity with a simple call:

    $this->client->getLatestRates(['symbols' => ['USD']]);
    

    If this fails, verify .env and API key permissions.

Extension Points

  1. Custom Responses: Override the default response parser by extending ExchangeRateHostClient:

    class CustomClient extends ExchangeRateHostClient {
        protected function parseResponse(ResponseInterface $response): array {
            // Custom logic
        }
    }
    
  2. Mocking for Tests: Use Symfony’s HTTP client mock:

    $client = $this->createMock(ClientInterface::class);
    $this->client->setHttpClient($client);
    
  3. Async Processing: Offload heavy time-series requests to a queue:

    dispatch(new ProcessTimeSeries($startDate, $endDate));
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
graham-campbell/flysystem
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
directorytree/opensearch-client
directorytree/opensearch-adapter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin