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

Technical Evaluation

Architecture Fit

  • Symfony/Laravel Compatibility: The package is designed for Symfony (not Laravel), but its architecture—PSR-7/17/18 compliance, service-based design, and config-driven approach—aligns well with Laravel’s ecosystem. A Laravel TPM could leverage it via:
    • Service Container Integration: Register the bundle as a Laravel service provider (adapting Symfony’s Bundle to Laravel’s ServiceProvider).
    • Facade Pattern: Wrap the ExchangeRateHostClientInterface in a Laravel facade for cleaner syntax (e.g., ExchangeRate::convert()).
    • PSR Standards: Laravel’s built-in HTTP client (Guzzle) and PSR-17 factories (symfony/http-foundation) can replace Symfony’s dependencies with minimal effort.
  • Domain Fit: Ideal for e-commerce, fintech, or multi-currency applications requiring real-time or historical exchange rates, VAT calculations, or currency conversions.

Integration Feasibility

  • High:
    • PSR Compliance: Laravel’s native support for PSR-18 (Guzzle) and PSR-17 (via symfony/http-foundation) eliminates dependency conflicts.
    • Configuration: The exchangerate_host.yaml config can be mirrored in Laravel’s config/exchangerate_host.php with minimal adaptation.
    • Caching: Laravel’s cache drivers (Redis, database, file) are compatible with Symfony’s cache pools, though the TPM may need to extend Laravel’s CacheManager for pool-specific configurations.
  • Challenges:
    • Symfony-Specific Features: The bundle uses Symfony’s Bundle system and DependencyInjection. A Laravel TPM would need to:
      • Replace the Bundle with a Laravel ServiceProvider.
      • Manually bind interfaces (e.g., ExchangeRateHostClientInterface) to implementations in the container.
    • Cache Pool Naming: Symfony’s cache pool names (e.g., exchangeratehost.cache) may conflict with Laravel’s naming conventions. A TPM could use Laravel’s Cache::store() or rename pools in the config.

Technical Risk

  • Low:
    • Maturity: The package is functional (86% test coverage) but lacks production-scale validation (0 stars, 0 dependents). Risk is mitigated by:
      • PSR Standards: Reduces coupling to Symfony-specific code.
      • API Stability: ExchangeRate.host’s API is well-documented and free-tier-friendly.
    • Cache Handling: The cron-based cache clearing (daily at 00:05 GMT) is a known limitation but aligns with the API’s data update schedule.
  • Moderate:
    • Unofficial Bundle: No affiliation with ExchangeRate.host could pose long-term support risks. Mitigation:
      • Fork the repo to customize or extend functionality.
      • Monitor the API’s roadmap (e.g., rate limits, breaking changes).
    • Error Handling: The bundle throws exceptions for invalid results (PR #11), but a TPM should layer additional Laravel-specific error handling (e.g., throw_if in service methods).

Key Questions for the TPM

  1. Use Case Priority:
    • Is real-time conversion (e.g., checkout flows) critical, or can cached rates suffice? This dictates cache TTL and fallback strategies.
    • Are historical rates or VAT calculations required, or just latest rates?
  2. API Key Management:
    • Should the API key be environment-variable-based (Laravel’s .env) or injected via a config file?
  3. Fallback Mechanisms:
    • How should the system handle API failures (e.g., rate limits, outages)? Options:
      • Retry logic (Laravel’s retry helper).
      • Fallback to a secondary API (e.g., spatie/laravel-currency).
  4. Testing Strategy:
    • Should tests mock the API client or use a local test instance of ExchangeRate.host?
    • How to test cache invalidation (e.g., manual cache clearing vs. cron jobs)?
  5. Performance:
    • Will the bundle’s PSR-18 HTTP client introduce overhead compared to Laravel’s native HTTP client? Benchmark if latency is critical.
  6. Long-Term Maintenance:
    • Is the TPM comfortable maintaining a fork if the original bundle stagnates?
    • Should the bundle be wrapped in a Laravel package (e.g., laravel-exchangeratehost) for easier updates?

Integration Approach

Stack Fit

  • Laravel Compatibility:
    • HTTP Client: Replace Symfony’s PSR-18 client with Laravel’s Guzzle integration:
      // config/app.php
      'http' => [
          'client' => GuzzleHttp\Client::class,
      ],
      
    • PSR-17 Factories: Use symfony/http-foundation (already in Laravel) for request/URI factories.
    • Cache: Leverage Laravel’s cache drivers (Redis recommended for performance):
      // config/cache.php
      'stores' => [
          'exchangeratehost' => [
              'driver' => 'redis',
              'connection' => 'cache',
          ],
      ],
      
  • Service Provider:
    • Create a Laravel ServiceProvider to:
      1. Bind ExchangeRateHostClientInterface to the bundle’s implementation.
      2. Register the config file (config/exchangerate_host.php).
      3. Publish config/migrations if needed (e.g., for cache pool setup).
      // app/Providers/ExchangeRateHostServiceProvider.php
      public function register()
      {
          $this->app->bind(
              ExchangeRateHostClientInterface::class,
              ExchangeRateHostClient::class
          );
          $this->mergeConfigFrom(__DIR__.'/../../config/exchangerate_host.php', 'exchangerate_host');
      }
      

Migration Path

  1. Phase 1: Dependency Setup
    • Install the bundle and PSR dependencies:
      composer require benjaminmal/exchangeratehost-bundle nyholm/psr7 symfony/http-client
      
    • Replace Symfony’s PSR-18 client with Laravel’s Guzzle (if not already present).
  2. Phase 2: Configuration
    • Adapt exchangerate_host.yaml to Laravel’s config/exchangerate_host.php:
      return [
          'cache' => [
              'enabled' => true,
              'pools' => [
                  'latest_rates' => 'exchangeratehost',
                  // ...
              ],
          ],
      ];
      
    • Configure cache pools in config/cache.php (see above).
  3. Phase 3: Service Integration
    • Register the ServiceProvider in config/app.php.
    • Create a facade for convenience:
      // app/Facades/ExchangeRate.php
      public static function convert(string $from, string $to, float $amount): float
      {
          return app(ExchangeRateHostClientInterface::class)->convertCurrency($from, $to, $amount);
      }
      
  4. Phase 4: Testing
    • Mock the ExchangeRateHostClientInterface in unit tests.
    • Test cache behavior with Laravel’s cache testing helpers.

Compatibility

  • Laravel Versions: Tested on PHP 8.1+ and Symfony 6.2+. Laravel 9/10 should work with minor adjustments (e.g., PSR-18 client binding).
  • Cache Systems: Redis, database, and file caches are supported. Prioritize Redis for distributed systems.
  • API Limits: ExchangeRate.host’s free tier has rate limits (e.g., 1,000 requests/day). Monitor usage and implement caching aggressively.

Sequencing

  1. Core Integration: Implement the bundle in a non-production environment first.
  2. Feature Validation: Test all API endpoints (latest rates, historical, VAT, etc.) with edge cases (e.g., unsupported currencies).
  3. Performance Tuning: Adjust cache TTLs and pool configurations based on usage patterns.
  4. Fallback Logic: Add retry mechanisms or secondary APIs for production.
  5. Monitoring: Log API failures and cache misses to identify bottlenecks.

Operational Impact

Maintenance

  • Pros:
    • Low Code Maintenance: The bundle abstracts API complexity; updates are minimal unless the API changes.
    • Cache Management: Laravel’s cache tools (e.g., php artisan cache:clear) simplify cache maintenance.
  • Cons:
    • Unofficial Bundle: Requires vigilance for API changes or bundle abandonment. Mitigate by:
      • Setting up a GitHub watch for the repo.
      • Documenting customizations (e.g., forked versions).
    • Cache Cron Job: Daily cache clearing must be scheduled (e.g., Laravel’s task scheduler):
      // app/Console/Kernel.php
      protected function schedule(Schedule $schedule)
      {
          $schedule->command('cache:clear exchangeratehost')->dailyAt('00:06');
      }
      

Support

  • Debugging:
    • API Issues: Use Laravel’s logging to trace HTTP requests/responses:
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