有料になった exchangeratesapi.io を無料の範囲内で使い倒すnpmパッケージを作ってみた


背景

無料かつ登録不要で使える為替取得APIとして exchangeratesapi.ioが有名でしたが、ついに2021年4月から登録必須&一分機能は有料のサブスクリプション契約が必須になってしまいました。

2021/04/03時点で、月額費用と使える機能は以下のようになっているようです。
個人的な記憶を頼りに、2021年3月まで無料で使えた機能についても並べています。

機能 〜2021年3月
無料機能
Free Basic Professional Business
月額 無料 無料 $10 $40 $80
月間リクエスト数 無制限 250
1,000
10,000 100,000 500,000
更新頻度 1日 1日 1時間 10分 60秒
履歴取得
HTTPS対応
基準通貨の切り替え
為替換算
時間枠クエリ
為替変動クエリ
サポート なし 限定的 Basic Premium Premium

新たなFreeプランの場合、リクエスト数は大きく制限されますが、1日1回しか更新されないデータなので250回/月もあれば、個人利用やちょっとしたバッチ処理程度であれば十分に感じます。
なお、PricingページにはFreeプランの月間リクエスト数は250ですが、登録後のダッシュボード画面では1,000になっていました。

HTTPS対応していない点については、もともとオープンデータを取得するだけのAPIなので大きなリスクにはならないように思います。ただ、APIキーが丸見えになるので、APIキーを抜かれて勝手に使われる可能性くらいは頭に入れておく必要があります。

次の基準通貨の切り替えができなくなる点ですが、個人的にはこれが最もインパクトの大きい変更だと感じています。EU中央銀行のデータを使っていることもあり、このAPIのデフォルトの基準通貨はEURです。
たとえばUSDとJPYのレートを取りたい!という時、従来はUSD基準のJPYのレートを取得というリクエストができたものの、新たなFreeプランではEUR基準のUSDとJPYのレートを取得というリクエストを投げた上で、自ら換算処理を行う必要が出てきます。
これが面倒くさい場合は、$10以上課金してBasicプランにする必要があります。

また、為替換算についても、無料枠のAPIで取得したデータを使って自分で換算処理を実装することで、対応可能です。

無料枠のAPIだけで有料相当の機能を作ってみた

ということで、新たなAPIについて考察していると、かなり機能は制限されたことはわかりましたが、無料枠のAPIにちょっとした換算ロジックを組み合わせると、有料で提供されている機能に相当するものを作れるような気がしてきたので、Node.jsで実際に作ってみました。

@ittkm/exchangeratesapi

できること

このパッケージで網羅している機能を、先程の一覧表に反映するとこんな感じです。

機能 〜2021年3月
無料機能
NEW Free Basic Professional Business
月額 無料 無料 無料 $10 $40 $80
月間リクエスト数 無制限 ≦ 250
≦ 1,000
250
1,000
10,000 100,000 500,000
更新頻度 1日 1日 1日 1時間 10分 60秒
履歴取得
HTTPS対応
基準通貨の切り替え
為替換算
時間枠クエリ
為替変動クエリ
サポート なし なし 限定的 Basic Premium Premium

さすがに、HTTPS対応はAPI側の話なので対応できませんが、従来の無料機能よりも多機能になりました。
月間リクエスト数が少し減るのは、時間枠クエリを使用する場合です。(裏で指定された日数分のAPIリクエストを行うため)

なお、レスポンスは有料版のAPI仕様に合わせてあるため互換性があります。

exchangeratesapi.io の有料化で頭を抱えている方の一助になれば幸いです。

以下、READMEの日本語訳

インストール

# via npm
npm install --save @ittkm/exchangeratesapi

# via yarn
yarn add @ittkm/exchangeratesapi

使い方

import exchangeratesapi from "@ittkm/exchangeratesapi";
// // または
// const exchangeratesapi = require("@ittkm/exchangeratesapi").default;

// https://exchangeratesapi.io/ で取得したAPIキーに書き換えてください
const API_KEY = "1234567890abcdefghijklmnopqrstuv";

async function exchangeratesapiSamples() {
  // API Keyを使って初期化
  const api = new exchangeratesapi(API_KEY);

  // 好きなAPIを呼び出す
  const exchangeRates = await api.latest();
  console.dir(exchangeRates);
}

使用例

/**
 * 最新レート取得 (初期設定)
 *  - 基準通貨: EUR
 *  - 対象通貨: すべて
 */
console.dir(await api.latest());

/**
 * 最新レート取得
 *  - 基準通貨: USD
 *  - 対象通貨: GBP, JPY, EUR
 */
const latestParameters = {
  base: "USD",
  symbols: ["GBP", "JPY", "EUR"],
};
console.dir(await api.latest(latestParameters));

/**
 * 日付指定で取得 (初期設定)
 *  - 日付未指定で最新レートを取得
 *  - 基準通貨: EUR
 *  - 対象通貨: すべて
 */
console.dir(await api.historical({}));

/**
 * 日付指定で取得
 *  - 対象日: 2013-12-24
 *  - 基準通貨: GBP
 *  - 対象通貨: USD, CAD, EUR
 */
const historicalParameters = {
  date: "2013-12-24",
  base: "GBP",
  symbols: ["USD", "CAD", "EUR"],
};
console.dir(await api.historical(historicalParameters));

/**
 * 為替換算 (最新レート)
 *  - GBP から JPY
 *  - 数量: 25
 */
console.dir(
  await api.convert({
    from: "GBP",
    to: "JPY",
    amount: 25,
  })
);

/**
 * 為替換算 (過去のレート使用)
 *  - GBP から JPY
 *  - 数量: 25
 *  - 対象日: 2018-02-22
 */
const convertParameters = {
  from: "GBP",
  to: "JPY",
  amount: 25,
  date: "2018-02-22",
};
console.dir(await api.convert(convertParameters));

/**
 * 時間枠指定で取得 (最小オプション)
 *  - 対象通貨: すべて
 */
console.dir(
  await api.timeseries({
    start_date: "2012-05-01",
    end_date: "2012-05-03",
  })
);

/**
 * 時間枠指定で取得 (通過指定)
 *  - 基準通貨: EUR
 *  - 対象通貨: USD, AUD, CAD
 */
const timeseriesParameters = {
  start_date: "2012-05-01",
  end_date: "2012-05-03",
  base: "EUR",
  symbols: ["USD", "AUD", "CAD"],
};
console.dir(await api.timeseries(timeseriesParameters));

レスポンス

exchangeratesapi.ioのレスポンスと互換性があります。

詳細は公式ドキュメントを参照してください。