Skip to content

Commit 788c2f4

Browse files
committed
docs: restructure doc/readme.md to align with the README
Add three orientation sections at the top of the doc so a developer or search engine landing on doc/readme.md directly gets the same value proposition as the README: - 'What is Swap?' (factual, ~5 lines) - 'When should you use Swap?' (factual, ~3 lines) - 'Why not call an exchange rate API directly?' (mirrors the README verbatim so the canonical phrasing is consistent across both surfaces) Drop the 'About this documentation' meta section; its orientation role is taken over by the three sections above. Compact 'Per-query options' from three sub-headings (cache_ttl, cache, cache_key_prefix) into a single options table plus one example block. Same information, denser and easier to scan. Trim the prose around the HTTP request caching example. Add one FAQ entry: 'How does Swap relate to Exchanger?' that points to the README's 'Which package should I use?' section, so the doc covers the ecosystem map without duplicating it. Update the index to reflect the new section order and the emoji-prefixed anchors. Net length: roughly the same as before; structure is clearer, the doc stands on its own for a discovery-stage reader, and vocabulary is aligned with the README ('currency conversion library', 'exchange rate provider', 'fallback chain', 'caching').
1 parent a5a29e5 commit 788c2f4

1 file changed

Lines changed: 60 additions & 51 deletions

File tree

doc/readme.md

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,55 @@
11
# Documentation
22

3-
## 📘 About this documentation
3+
## 💡 What is Swap?
44

5-
This documentation covers the practical use of Swap, the PHP currency conversion library: configuration, caching, provider configuration, and how to write your own provider. For an overview of the library and the wider ecosystem (Exchanger, Laravel Swap, Symfony Swap), see the [README](../README.md).
5+
- Swap is a PHP library for currency conversion and exchange rate retrieval.
6+
- It exposes a wide range of exchange rate providers behind a common interface.
7+
- It caches results via PSR-16 SimpleCache.
8+
- It supports historical rates.
9+
- It supports a fallback chain. When a provider errors, the next provider in the chain is tried.
10+
11+
For the wider ecosystem (Exchanger, Laravel Swap, Symfony Swap), see the [README](../README.md).
12+
13+
## 🎯 When should you use Swap?
14+
15+
- Use Swap when you need to retrieve exchange rates in a PHP application: currency conversion workflows, multi-currency pricing, invoice totals, reconciliation, or historical FX data.
16+
- Use the lower-level [Exchanger](https://github.com/florianv/exchanger) library when Swap's defaults are too opinionated and you want finer control over chain composition, caching, or HTTP plumbing.
17+
18+
## 🧠 Why not call an exchange rate API directly?
19+
20+
You can integrate a single exchange rate API directly in your application.
21+
22+
Swap is useful when you need more than a single provider:
23+
24+
- **Provider abstraction** — switch providers without rewriting your code
25+
- **Fallback support** — if one provider fails, another can be used automatically
26+
- **Unified interface** — all providers share the same API
27+
- **Caching** — reduce API calls and improve performance
28+
- **Flexibility** — combine public and commercial providers
29+
30+
For simple use cases, calling a single API may be enough.
31+
32+
Swap becomes valuable when you need reliability, flexibility, or long-term maintainability.
633

734
## Index
835

9-
* [Installation](#installation)
10-
* [Configuration](#configuration)
36+
* [Installation](#-installation)
37+
* [Configuration](#-configuration)
1138
* [Building Swap](#building-swap)
1239
* [Adding multiple providers](#adding-multiple-providers)
1340
* [How the fallback chain works](#how-the-fallback-chain-works)
14-
* [Usage](#usage)
41+
* [Usage](#-usage)
1542
* [Retrieving rates](#retrieving-rates)
1643
* [Inspecting the rate](#inspecting-the-rate)
17-
* [Caching](#caching)
44+
* [Caching](#-caching)
1845
* [PSR-16 SimpleCache (minimal setup)](#psr-16-simplecache-minimal-setup)
1946
* [Per-query options](#per-query-options)
2047
* [HTTP request caching](#http-request-caching)
21-
* [Provider configuration](#provider-configuration)
22-
* [Creating a custom service](#creating-a-custom-service)
48+
* [Provider configuration](#-provider-configuration)
49+
* [Creating a custom service](#-creating-a-custom-service)
2350
* [Standard service](#standard-service)
2451
* [Historical service](#historical-service)
25-
* [FAQ](#faq)
52+
* [FAQ](#-faq)
2653

2754
## 📦 Installation
2855

@@ -56,7 +83,7 @@ $swap = (new Builder())
5683
->build();
5784
```
5885

59-
`add()` registers a provider by its identifier (the string passed to `Builder::add()`, for example `european_central_bank`). The full list of identifiers is in the README's [Providers table](../README.md#providers).
86+
`add()` registers a provider by its identifier (the string passed to `Builder::add()`, for example `european_central_bank`). The full list of identifiers is in the README's [Providers table](../README.md#-providers).
6087

6188
### Adding multiple providers
6289

@@ -72,7 +99,7 @@ $swap = (new Builder())
7299
->build();
73100
```
74101

75-
Identifiers and the configuration keys each one accepts are documented in the [Provider configuration](#provider-configuration) section.
102+
Identifiers and the configuration keys each one accepts are documented in the [Provider configuration](#-provider-configuration) section.
76103

77104
### How the fallback chain works
78105

@@ -159,49 +186,30 @@ $cache = new SimpleCacheBridge(new PredisCachePool($client));
159186

160187
### Per-query options
161188

162-
Cache behavior can be overridden per call.
163-
164-
#### `cache_ttl`
165-
166-
Cache TTL in seconds. Default: `null` (cache entries do not expire).
167-
168-
```php
169-
$rate = $swap->latest('EUR/USD', ['cache_ttl' => 60]);
170-
$rate = $swap->historical('EUR/USD', $date, ['cache_ttl' => 60]);
171-
```
189+
Cache behavior can be overridden per call by passing an options array to `latest()` or `historical()`.
172190

173-
#### `cache`
191+
| Option | Type | Default | Effect |
192+
| ------------------ | ------ | ------- | ----------------------------------------------------------------------------------------------------- |
193+
| `cache_ttl` | int | `null` | Cache TTL in seconds. `null` means entries do not expire. |
194+
| `cache` | bool | `true` | Set to `false` to bypass the cache for this call. |
195+
| `cache_key_prefix` | string | `""` | Prefix for the cache key. Max 24 characters (PSR-6 limits keys to 64 chars; the internal hash takes 40). |
174196

175-
Disable or enable caching for a single query. Default: `true`.
197+
PSR-6 does not allow the characters `{}()/\@:` in keys; Swap replaces them with `-`.
176198

177199
```php
178200
$rate = $swap->latest('EUR/USD', ['cache' => false]);
179-
$rate = $swap->historical('EUR/USD', $date, ['cache' => false]);
180-
```
181-
182-
#### `cache_key_prefix`
183-
184-
Override the cache key prefix for a single query. Default: empty string.
185-
186-
PSR-6 limits cache keys to 64 characters. The internal hash of the query takes 40 characters, so the prefix must not exceed 24 characters. PSR-6 also does not allow the characters `{}()/\@:` in keys; Swap replaces them with `-`.
187-
188-
```php
201+
$rate = $swap->latest('EUR/USD', ['cache_ttl' => 60]);
189202
$rate = $swap->latest('EUR/USD', ['cache_key_prefix' => 'currencies-special-']);
190-
$rate = $swap->historical('EUR/USD', $date, ['cache_key_prefix' => 'currencies-special-']);
191203
```
192204

193205
### HTTP request caching
194206

195-
Some providers return all rates for a given base currency in a single response. If you fetch several pairs sharing the same base (for example `EUR/USD` and then `EUR/GBP`), caching the underlying HTTP response avoids hitting the provider twice.
196-
197-
Install the PHP HTTP cache plugin and a PSR-6 cache adapter:
207+
Some providers return all rates for a given base currency in a single response. If you fetch several pairs sharing the same base (for example `EUR/USD` and then `EUR/GBP`), caching the underlying HTTP response avoids hitting the provider twice. Decorate your HTTP client with the PHP HTTP cache plugin and pass it to `Builder::useHttpClient()`:
198208

199209
```bash
200210
composer require php-http/cache-plugin cache/array-adapter
201211
```
202212

203-
Decorate your HTTP client with the cache plugin and pass it to `Builder::useHttpClient()`:
204-
205213
```php
206214
use Cache\Adapter\PHPArray\ArrayCachePool;
207215
use Http\Adapter\Guzzle7\Client as GuzzleClient;
@@ -220,11 +228,8 @@ $swap = (new Builder())
220228
->add('european_central_bank')
221229
->build();
222230

223-
// First call performs an HTTP request
224-
$rate = $swap->latest('EUR/USD');
225-
226-
// Second call hits the HTTP cache
227-
$rate = $swap->latest('EUR/GBP');
231+
$rate = $swap->latest('EUR/USD'); // performs an HTTP request
232+
$rate = $swap->latest('EUR/GBP'); // hits the HTTP cache
228233
```
229234

230235
## 🔑 Provider configuration
@@ -263,9 +268,9 @@ Example:
263268

264269
```php
265270
$swap = (new Builder())
266-
->add('apilayer_fixer', ['api_key' => 'YOUR_KEY'])
267-
->add('open_exchange_rates', ['app_id' => 'YOUR_APP_ID', 'enterprise' => false])
268-
->add('xignite', ['token' => 'YOUR_TOKEN'])
271+
->add('apilayer_fixer', ['api_key' => 'YOUR_KEY'])
272+
->add('open_exchange_rates', ['app_id' => 'YOUR_APP_ID', 'enterprise' => false])
273+
->add('xignite', ['token' => 'YOUR_TOKEN'])
269274
->build();
270275
```
271276

@@ -280,7 +285,7 @@ $swap = (new Builder())
280285
->build();
281286
```
282287

283-
The full provider list with capabilities (base currency, quote currency, historical support) is in the README's [Providers table](../README.md#providers).
288+
The full provider list with capabilities (base currency, quote currency, historical support) is in the README's [Providers table](../README.md#-providers).
284289

285290
## 🧩 Creating a custom service
286291

@@ -370,7 +375,11 @@ Swap throws an `Exchanger\Exception\ChainException`. Calling `$exception->getExc
370375

371376
#### Can I use Swap without an API key?
372377

373-
Yes. The European Central Bank, the national banks, `cryptonator`, `exchangeratehost`, and `webservicex` do not require an API key. See the [Providers table](../README.md#providers) for the full list.
378+
Yes. The European Central Bank, the national banks, `cryptonator`, `exchangeratehost`, and `webservicex` do not require an API key. See the [Providers table](../README.md#-providers) for the full list.
379+
380+
#### How does Swap relate to Exchanger?
381+
382+
Swap is the high-level, easy-to-use API. Exchanger is the lower-level provider layer Swap is built on. Reach for Exchanger directly only when you need finer control over chain composition, caching, or HTTP plumbing. See the README's [Which package should I use?](../README.md#-which-package-should-i-use) section.
374383

375384
#### How do I cache rates?
376385

@@ -382,8 +391,8 @@ Pass `['cache' => false]` as the options argument: `$swap->latest('EUR/USD', ['c
382391

383392
#### How do I add my own provider?
384393

385-
Implement `Exchanger\Contract\ExchangeRateService` (or extend `HttpService` / `Service`), register it with `Swap\Service\Registry::register()`, then call `Builder::add()` with your identifier. See [Creating a custom service](#creating-a-custom-service).
394+
Implement `Exchanger\Contract\ExchangeRateService` (or extend `HttpService` / `Service`), register it with `Swap\Service\Registry::register()`, then call `Builder::add()` with your identifier. See [Creating a custom service](#-creating-a-custom-service).
386395

387396
#### Where is the full provider list with capabilities?
388397

389-
In the README's [Providers table](../README.md#providers). It lists every supported identifier with its base currency, quote currency, and historical support.
398+
In the README's [Providers table](../README.md#-providers). It lists every supported identifier with its base currency, quote currency, and historical support.

0 commit comments

Comments
 (0)