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

Exchanger Laravel Package

florianv/exchanger

Exchange rate provider layer for PHP: 30+ rate services behind one ExchangeRateService interface. Supports historical rates, chain fallback between providers, and PSR-16 caching. Use when you need more control than higher-level libraries.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Microservice/Modular Fit: Ideal for Laravel applications requiring decoupled currency conversion logic (e.g., e-commerce, fintech, multi-currency platforms). The ExchangeRateService interface enables dependency injection and mocking for testing.
  • Layered Design: Aligns with Laravel’s service layer pattern (e.g., App\Services\CurrencyService). Can be wrapped in a facade or service container binding for seamless integration.
  • PSR Compliance: Leverages PSR-16 (Cache), PSR-18 (HTTP Client), and PSR-7 (HTTP Messages), ensuring compatibility with Laravel’s ecosystem (e.g., Illuminate\Cache, GuzzleHttp\Client).
  • Fallback Chain: Critical for high availability—supports graceful degradation if primary APIs fail (e.g., fastFOREX → ECB fallback).

Integration Feasibility

  • Laravel-Specific Synergies:
    • Service Container: Bind Exchanger to Laravel’s IoC container via AppServiceProvider:
      $this->app->singleton(ExchangeRateService::class, function ($app) {
          return new Exchanger(new Chain([
              new FastForex(null, null, ['api_key' => config('services.fastforex.key')]),
              new EuropeanCentralBank(),
          ]));
      });
      
    • Config Integration: Store API keys in config/services.php and inject via config('services.fastforex.key').
    • Cache Backend: Use Laravel’s cache drivers (e.g., file, redis) with PSR-16 bridge (php-cache/simple-cache-bridge).
  • Middleware Support: Extend HttpService to add Laravel middleware (e.g., logging, retries) via PSR-15.

Technical Risk

  • PHP 8.2+ Requirement: Laravel 10+ (PHP 8.1+) may need minor adjustments (e.g., strict_types=1).
  • API Key Management: Risk of hardcoded keys if not abstracted via Laravel’s config/environment variables.
  • Rate Limiting: Commercial APIs (e.g., fastFOREX) may throttle requests; requires exponential backoff or queue-based processing.
  • Historical Data: Some providers (e.g., ECB) have limited historical granularity; ensure alignment with business needs.
  • Testing Complexity: Mocking external APIs requires stubbing HTTP responses (e.g., Mockery + GuzzleHttp\Psr7).

Key Questions

  1. Primary Use Case:
    • Real-time conversions (e.g., checkout) vs. batch processing (e.g., reporting)?
    • Required currency pairs (e.g., EUR/USD vs. niche pairs like GBP/TRY)?
  2. Fallback Strategy:
    • Should failures log errors or silently degrade?
    • Need for custom fallback logic (e.g., weighted averages)?
  3. Performance:
    • Cache TTL: How often do rates need refreshing (e.g., hourly vs. real-time)?
    • Concurrency: Will multiple services run in parallel (e.g., via Laravel Queues)?
  4. Observability:
    • Requirement for metrics (e.g., Prometheus) or tracing (e.g., OpenTelemetry)?
  5. Compliance:
    • Need for audit logs of currency conversions (e.g., for financial regulations)?

Integration Approach

Stack Fit

  • Laravel Ecosystem:
    • Service Container: Replace manual instantiation with Laravel bindings.
    • Cache: Use Illuminate\Cache with PSR-16 bridge (e.g., Cache::store('redis')->get()).
    • HTTP Client: Leverage GuzzleHttp\Client (default in Laravel) or Symfony HttpClient.
    • Queues: Offload rate fetching to delayed jobs (e.g., fetchExchangeRatesJob) for batch processing.
  • Database:
    • Store historical rates in a exchange_rates table with currency_from, currency_to, rate, date, and provider columns.
    • Use Laravel Scout for full-text search if querying by currency pair.

Migration Path

  1. Phase 1: Proof of Concept
    • Integrate Exchanger in a single controller (e.g., CurrencyController) for testing.
    • Use EuropeanCentralBank (free) as primary provider.
    • Validate rate accuracy against a known source (e.g., XE.com).
  2. Phase 2: Core Integration
    • Bind Exchanger to Laravel’s service container (see above).
    • Configure fastFOREX as primary provider with ECB fallback.
    • Implement PSR-16 caching (e.g., Redis with 1-hour TTL).
  3. Phase 3: Production Hardening
    • Add rate limiting (e.g., throttle middleware for API calls).
    • Instrument with Laravel Telescope or Sentry for error tracking.
    • Optimize historical data storage (e.g., partition by year).

Compatibility

  • Laravel Versions:
    • Laravel 10+: Native PHP 8.2+ support; minimal changes needed.
    • Laravel 9: May require PHP 8.1 compatibility layer (e.g., str_contains polyfill).
  • Existing Code:
    • Replace hardcoded rate sources (e.g., config('currencies.rates')) with Exchanger calls.
    • Update unit tests to mock ExchangeRateService instead of static rates.
  • Third-Party Packages:
    • Conflict risk with florianv/swap (higher-level library); avoid duplication.

Sequencing

  1. Dependency Installation:
    composer require florianv/exchanger symfony/http-client nyholm/psr7 php-cache/simple-cache-bridge
    
  2. Configuration:
    • Add API keys to .env:
      FASTFOREX_API_KEY=your_key_here
      
    • Publish config (if extending):
      php artisan vendor:publish --provider="Florianv\Exchanger\ExchangerServiceProvider"
      
  3. Service Binding:
    • Register in AppServiceProvider::boot():
      $this->app->singleton(ExchangeRateService::class, function ($app) {
          $cache = Cache::store('redis')->getPsr16Cache();
          return new Exchanger(
              new Chain([new FastForex(null, null, ['api_key' => config('services.fastforex.key')])]),
              $cache
          );
      });
      
  4. Usage:
    • Inject ExchangeRateService into controllers/services:
      public function convert(Currency $amount, string $toCurrency): float
      {
          $query = (new ExchangeRateQueryBuilder($amount->currency . '/' . $toCurrency))->build();
          $rate = $this->exchangeRateService->getExchangeRate($query);
          return $amount->value * $rate->getValue();
      }
      

Operational Impact

Maintenance

  • Updates:
    • Monitor GitHub releases for breaking changes (e.g., PHP 8.2+ requirement in v2.9.0).
    • Dependency updates via composer update florianv/exchanger (test thoroughly).
  • Provider-Specific:
    • API key rotation: Implement a key refresh mechanism (e.g., Laravel Horizon cron job).
    • Deprecated providers: Remove unused services from the chain (e.g., Yahoo was deprecated in v2.0.0).
  • Cache Management:
    • Cache invalidation: Clear cache on config('services.fastforex.key') changes.
    • Monitor cache hit/miss ratios (e.g., via Laravel Debugbar).

Support

  • Troubleshooting:
    • Rate discrepancies: Compare Exchanger output with XE.com or ECB.
    • API failures: Check ChainException for underlying errors (e.g., rate limits, network issues).
  • Logging:
    • Log provider names and response times for debugging:
      $rate = $this->exchangeRateService->getExchangeRate($query);
      logger()->info("Fetched {$rate->getCurrencyPair()} from {$rate->getProviderName()}");
      
  • Documentation:
    • Add internal docs for:
      • Supported currency pairs.
      • Fallback chain order.
      • Cache strategy
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony