Skip to content

Add UniRateAPI service - #180

Merged
alies-dev merged 1 commit into
florianv:masterfrom
rob-browncc:add-unirate-api-service
May 18, 2026
Merged

Add UniRateAPI service#180
alies-dev merged 1 commit into
florianv:masterfrom
rob-browncc:add-unirate-api-service

Conversation

@rob-browncc

Copy link
Copy Markdown
Contributor

What

Adds Exchanger\Service\UniRateApi (registry identifier unirate_api) — a new commercial provider for UniRateAPI.

Why

UniRateAPI is a free-tier-first JSON FX API covering ~170 fiat + crypto currencies, historical rates back to 1999 (paid), and the usual conversion / time-series / VAT endpoints. Adding it to Exchanger gives users a no-credit-card-required option to drop into a Chain alongside or in front of ECB/Fixer/fastFOREX.

Surface

  • Exchanger\Service\UniRateApi extends HttpService with SupportsHistoricalQueries
  • Required option: api_key
  • Latest: GET /api/rates?api_key=…&from=…&to=…{"rate": "0.92"}
  • Historical: GET /api/historical/rates?api_key=…&date=YYYY-MM-DD&from=…&to=…{"rate": "0.91"} (paid plan)
  • Registry alias: unirate_api
  • Test coverage: 8 tests, 36 assertions (mocked HTTP adapter + JSON fixtures, same shape as FastForexTest)
  • phpunit full suite: 285 tests, 1380 assertions — all green on PHP 8.3 inside the container I tested
  • psalm clean (baseline updated with the same MissingOverrideAttribute entries already used for the other services)
  • README + doc/readme.md provider tables updated; provider count bumped 30 → 31

Files

  • src/Service/UniRateApi.php — new
  • src/Service/Registry.php — register alias
  • tests/Tests/Service/UniRateApiTest.php — new
  • tests/Fixtures/Service/UniRateApi/{rate-usd-eur,historical-usd-eur,error-invalid-currency}.json — new
  • README.md + doc/readme.md — service tables + count
  • psalm-baseline.xmlMissingOverrideAttribute baseline parity

Disclosure

I work on UniRateAPI. The PR is intentionally additive and follows the existing service pattern (closest reference: FastForex / CurrencyDataFeed). Happy to take a different naming choice for the registry alias, drop the README mentions, or split the doc edit out — let me know.

Adds `Exchanger\Service\UniRateApi` (registry identifier `unirate_api`),
covering both latest and historical rate queries against
https://unirateapi.com.

The free tier supports the latest endpoint with all 170+ currencies;
historical rates require a paid plan and are surfaced through the same
`HistoricalExchangeRateQuery` path so chaining and caching work
unchanged.

Tests follow the FastForex pattern (mocked HTTP adapter + JSON
fixtures). Psalm baseline updated with the same `MissingOverrideAttribute`
entries used for the other services.

- src/Service/UniRateApi.php        new HttpService implementation
- src/Service/Registry.php          register `unirate_api`
- tests/Tests/Service/UniRateApiTest.php   8 tests, 36 assertions
- tests/Fixtures/Service/UniRateApi/       latest, historical, error
- README.md + doc/readme.md         service tables + count bumped to 31
- psalm-baseline.xml                MissingOverrideAttribute entries

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new UniRateApi service provider to Exchanger, registered as unirate_api, supporting both latest and historical exchange rate queries with an api_key option. Mirrors the structure of existing services such as FastForex.

Changes:

  • New Exchanger\Service\UniRateApi class implementing HttpService + SupportsHistoricalQueries with processOptions, getLatestExchangeRate, getHistoricalExchangeRate.
  • Registered alias unirate_api in Registry and added Psalm baseline entries.
  • New PHPUnit tests + JSON fixtures and provider table/count updates in README/doc.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Service/UniRateApi.php New service class for UniRateAPI endpoints (latest + historical).
src/Service/Registry.php Registers unirate_api alias.
tests/Tests/Service/UniRateApiTest.php Unit tests covering options, queries, errors, and naming.
tests/Fixtures/Service/UniRateApi/*.json Mock JSON responses for tests.
README.md Updates provider count 30 → 31 and adds row to commercial table.
doc/readme.md Adds UniRateApi row to options table.
psalm-baseline.xml Adds MissingOverrideAttribute entries for new class methods.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alies-dev alies-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rob-browncc

Thank you for the contribution — looks great! I'll tune Psalm and docs to make the PR workflow even more friendly.

Thank you again!

@alies-dev
alies-dev merged commit 3d30f5d into florianv:master May 18, 2026
10 checks passed
alies-dev pushed a commit to florianv/swap that referenced this pull request Jun 17, 2026
Exchanger merged UniRateAPI support in florianv/exchanger#180. Swap
auto-inherits provider services from Exchanger's Registry, so
`->add('unirate_api', ['api_key' => getenv('UNIRATE_API_KEY')])` already
works on master; only the docs were missing.

- README.md: add row to commercial providers table (alphabetical
  position between `open_exchange_rates` and `webservicex`); bump
  provider counts 30 → 31 in tagline, providers section, and the
  Exchanger sibling-package line.
- doc/readme.md: add `unirate_api` / `api_key` row to the commercial
  config table.

UniRateAPI is a commercial REST API for FX (latest rates on the free
tier; historical and commodities on the paid tier — same shape as the
other paid providers in the table).
alies-dev pushed a commit to florianv/laravel-swap that referenced this pull request Jun 17, 2026
Exchanger merged UniRateAPI support in florianv/exchanger#180 and Swap's
docs PR is florianv/swap#155. Laravel Swap auto-inherits the underlying
Swap service list, so `'unirate_api' => ['api_key' => env(...)]` already
works on master once the next Exchanger release tag lands; only the docs
and the published config stub were missing.

- config/swap.php: add `unirate_api` to the in-file docblock spec list
  (after `xchangeapi`) and add a commented-out example line to the
  `services` array next to the other commercial providers, mirroring
  the existing `apilayer_fixer` / `open_exchange_rates` examples.
- README.md: add `UniRateAPI` row to the commercial provider table
  (alphabetical, between `open_exchange_rates` and `webservicex`);
  bump count 30 → 31.
- doc/readme.md: add `unirate_api` / `api_key` row to the commercial
  configuration table.

UniRateAPI is a commercial REST API for FX. Latest rates are on the
free tier; historical and commodities are paid-tier only — the upstream
`Exchanger\Service\UniRateApi` maps HTTP 403 on those endpoints to
`Exchanger\Exception\ChainException`, matching the existing fastFOREX /
Fixer plan-gated behaviour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants