使用ExchangeRate-API查询免费可用的汇率数据

姜玉泽
2023-12-01

去年, 我写了一篇关于使用Groovy编程语言从API访问汇率数据以简化我的费用记录的文章。 我展示了两个汇率站点fixer.io和apilayer.net(现为apilayer.com )如何提供所需的数据,使我可以使用前者在印度卢比(INR) 和加元(CAD)之间进行转换,以及智利比索(CLP)和加拿大元使用后者。

最近,David在ExchangeRate-API.com上与我联系说:“您提到的免费API(Fixer)已由CurrencyLayer购买,并且已禁止其无注册/无限制访问权限。” 他还告诉我,“我运行了一个免费的API,称为ExchangeRate-API.com,它具有与原始Fixer相同的JSON格式,不需要任何注册,并且允许无限制的请求。”

交换了几封电子邮件之后,我们决定将我们的对话变成一次采访。 在采访下方,您可以找到脚本和使用说明 。 (为清晰起见,对采访进行了稍微的编辑。)

关于ExchangeRate-API

克里斯: ExchangeRate-API与其他在线汇率服务有何不同? 是什么促使您提供这项服务?

大卫:2010年当我和一个朋友一起启动ExchangeRate-API时,我们免费构建和发布了它,因为我们确实需要为另一个项目提供此服务,并且尽管进行了广泛的谷歌搜索却找不到。 现在大约有20种此类API提供了许多不同的方法。 多年来,我尝试了许多不同的方法,但是免费提供高质量数据始终被证明是最受欢迎的方法。 我也为这样的想法感到鼓舞:即使没有预算,想要构建有用的东西的开发人员也应该可以自由访问这些数据。

因此,我们的货币换算API的主要区别在于它是不受限制的,不需要注册。 这也使得开始真正使用它非常快-您只需复制端点URL,就可以了。

还有另外一两个免费且无限制的API,但这些API通常仅用于满足欧洲中央银行提供的每日参考汇率。 ExchangeRate-API从许多中央银行收集公共参考汇率,然后将它们混合以降低价值偏高的风险。 它还会进行验收检查,以确保汇率没有大错(例如,反向数据捕获将美元记录为CLP,而不是CLP记录为USD),并根据其历史准确性对不同来源进行加权。 这使得服务相当可靠。 我目前正在做一个透明度项目,以比较并显示此公开参考汇率与专有数据源的准确性,以便潜在用户可以就哪种货币数据服务适合他们做出更明智的决定。

克里斯:我很高兴您包括加元和印度卢比,因为这是我需要解决的问题。 我很伤心地看到,你不必智利比索(另一个问题,我需要解决)。 您能告诉我们如何选择货币列表吗? 您是否期望将其他货币添加到您的列表中?

David:因为我这项服务的主要目的是提供稳定和可靠的汇率数据,所以只有在该货币代码有多个数据源的情况下,我才包含货币。 例如,在您提到要查找CLP数据之后,我将智利中央银行发布的每日参考汇率添加到了系统中。 如果我可以找到其他包含CLP的来源,它将被包含在我们支持的货币列表中,但不幸的是,直到那时为止。 目标是支持尽可能多的货币。

需要注意的一件事是,对于某些货币,该服务至少具有两个来源,但是几乎每套公共参考汇率中都包含了几对货币(例如,USD / EUR)。 我提到的透明准确性项目有望使这一区别变得清晰,以便用户可以理解为什么我们的USD / EUR汇率可能比CLP / INR等较不常见的货币对更准确,以及货币对之间的准确性差异程度。 需要花一些时间才能使显示这些信息变得快速且容易理解。

API的架构

克里斯:您能谈谈您API的体系结构吗? 您是否使用开源组件来提供服务?

David:我专门使用开源软件来运行ExchangeRate-API。 我绝对是一名开放源代码爱好者,并且总是吸引朋友切换到开放源代码,解释许可证并在有条件时向我最常使用的项目捐款。 我还尝试通过电子邮件向我曾表示感谢的项目的维护者发送电子邮件,但我做得还不够。

该堆栈当前为Ubuntu LTS,MariaDB,Nginx,PHP 7和Memcached。 我还使用Bootstrap和Picnic开源CSS框架。 我通过电子前沿基金会的开源ACME客户端Certbot使用Let's Encrypt获得HTTPS证书。 该服务广泛使用了UFW / iptables,cURL,OpenSSH和Git等经典工具。

我的方法通常是在使用久经考验的开源构建基块时,使所有内容尽可能简单。 对于旨在始终可供用户进行货币兑换的项目,这感觉就像是获得可靠性的最佳途径。 我喜欢阅读有关可能对诸如此类的项目(例如CockroachDB)有用的创新性新项目的信息,但是直到它们被认为是真正的防弹产品之前,我才会使用它们。 显然,像Heartbleed这样的事情表明“无聊”项目也存在风险,但是我认为,与较新的,最前沿的项目相比,这些风险比潜在的未知风险更容易管理。

在基础架构设置方面,过去九年来我一直在稳步构建和改进该系统,现在该系统大致包括三层。 主集群在Amazon Web Services(AWS)上运行,由Ubuntu EC2服务器和高可用性MariaDB关系数据库服务(RDS)实例组成。 EC2实例分布在多个AWS可用区中,并以托管的AWS Elastic Load Balancing(ELB)服务为前端。 在具有自动跨区域故障转移功能的RDS数据库实例与跨可用性区域分布的,面向ELB的EC2实例之间,此设置非常有用。 但是,它仅在一个区域设置中。 因此,我在不同的地理位置设置了第二层虚拟专用服务器(VPS)实例,以减少延迟并将负载分配到更昂贵的AWS基础架构上。 这些当前与Linode一起使用,但是最近我也使用了DigitalOcean和Vultr。

最后,这一切都在Cloudflare的保护之下。 借助免费服务,不可避免地会有一些用户选择滥用该系统,而Cloudflare是一款出色的产品,对ExchangeRate-API至关重要。 我们的服务器可以受到保护,我们的用户可以获得低延迟的区域内缓存。 Cloudflare设置了负载平衡和流量控制产品,以减少延迟并立即将流量从基础架构的不正常部分转移到可用来源。

使用这种非常冗余的方法,三年来没有因基础架构问题或用户负载而导致的停机时间。 这段时间经历的几次降级服务都是由于代码,部署策略或配置错误引起的。 该设置目前每月处理低负载级别和可管理成本的亿万个请求,因此还有很大的增长空间。

实际的应用程序代码是大量使用MemcachedPHP。 Memcached是Brad Fitzpatrick于2003年发起的一个令人惊叹的开源项目。它虽然不是特别迷人,但是它是一个非常可靠且性能卓越的分布式内存中键值存储。

与开源社区合作

克里斯:您的配置中有大量开源。 在这些项目中,您如何与更广泛的用户社区互动?

大卫:我真的很难在成为副项目SaaS的时候成为最好的开源公民。 我曾考虑过构建某种形式的开源库并发布它,但我没有想到尚未完成的事情,并且我将做出时间上的承诺进行可靠维护。 如果可以确信,我将有足够的时间来确保选择该项目的用户不会突然发现自己依赖于废弃软件,那么我只会启动这样的项目。 我还考虑为ExchangeRate-API所依赖的项目做出贡献,但是由于我仅使用最大,最成熟的选项,因此我缺乏专业知识来为如此严肃的项目做出有意义的贡献。

我目前正在为该服务制定新的“专业版”计划,并且我将设置此收入的百分比以捐赠给我的开源依赖项。 但是,这仍然像绷带一样—回答这个问题使我意识到我需要花更多的时间来启动一个名为ExchangeRate-API的开源项目!

展望未来

克里斯:我们只能查询最新汇率,但看来您可能会在今年晚些时候提供历史汇率。 您能否告诉我们更多有关提供历史数据的技术挑战?

大卫:有一个历史汇率数据集,它使用我们的相同算法从多个中央银行参考集中混合而成。 但是,由于数据质量方面的一些问题,我为此停止了新的注册。 该数据集可以追溯到1990年,并且有一些早期时期需要更好的数据验证。 因此,我正在构建一个更好的系统来检查和比较提取的数据,并添加其他数据源。 该计划将在今年晚些时候提供一个干净且更全面地验证准确的数据集。

在技​​术方面,历史数据比实时数据稍微复杂一些。 与实时数据集(仅几个字节)相比,历史数据是数百万个数据库行。 该数据最初是从具有较长生存时间(TTL)中间缓存层的数据库基础结构提供的。 这在很大程度上是很有效的,但是在用户想要以网络能够处理的最快速度转储整个数据集的情况下却很困难。 如果缓存足够暖和,那很好,但是如果最近重新启动,部署新服务器等,则这些大请求集将在缓存上“遗失”足够多,以至于数据库将出现问题的峰值负载。

显然,目标是一种基础架构,该架构甚至可以处理具有正常性能的激进用例,因此新的历史汇率数据集将带有抢先式内存中缓存,而不是请求驱动的缓存。 幸运的是,RAM现在便宜了,即使对于像ExchangeRate-API.com这样的小型项目,也要完全将数百兆字节的数据放入RAM中,这似乎是一种可行的方法。

克里斯:听起来您已经遍历了此服务的许多迭代才能到达今天! 您如何看待未来几年的发展?

戴维:我的目标是使它涵盖所有世界货币,以便寻找这种软件的任何人都可以轻松地以编程方式免费获得所需的汇率。

我也绝对希望有一个价格合理的Pro计划,能引起用户的共鸣。 做到这一点将意味着更好的基础架构和更低的免费用户延迟。

最后,我想在ExchangeRate-API旗帜下拥有某种有用的开源库。 启动一个发现一个热情社区的小项目将是非常有益的。 运行像啤酒一样免费的东西很棒,但是如果其中的一部分也可以像语音一样自由,那就更好了。

如何使用服务

使用wget测试服务很容易,如下所示:


   
   
clh@marseille:~$ wget -O - https://api.exchangerate-api.com/v4/latest/INR
--2019-04-26 13:48:23--  https://api.exchangerate-api.com/v4/latest/INR
Resolving api.exchangerate-api.com (api.exchangerate-api.com)... 2606:4700:20::681a:c80, 2606:4700:20::681a:d80, 104.26.13.128, ...
Connecting to api.exchangerate-api.com (api.exchangerate-api.com)|2606:4700:20::681a:c80|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/json]
Saving to: ‘STDOUT’

-                                    [<=>                                                      
]       0  --.-KB/s               {"base":"INR","date":"2019-04-26","time_last_updated":1556236800,"rates":{"INR":1,"AUD":0.020343,"BRL":0.056786,"CAD":0.019248,"CHF":0.014554,"CNY":0.096099,"CZK":0.329222,"DKK":0.095497,"EUR":0.012789,"GBP":0.011052,"HKD":0.111898,"HUF":4.118615,"IDR":199.61769,"ILS":0.051749,"ISK":1.741659,"JPY":1.595527,"KRW":16.553091,"MXN":0.272383,"MYR":0.058964,"NOK":0.123365,"NZD":0.02161,"PEN":0.047497,"PHP":0.744974,"PLN":0.054927,"RON":0.060923,"RUB":0.921808,"SAR":0.053562,"SEK":0.135226,"SGD":0.019442,"THB":0.457501,"TRY":0-                                    [ <=>                                                      ]     579  --.-KB/s    in 0s      

2019-04-26 13:48:23 (15.5 MB/s) - written to stdout [579]

clh@marseille:~$

结果以JSON负载的形式返回,从而给出了从印度卢比(我在URL中请求的货币)到ExchangeRate-API处理的所有货币的转换率。

Groovy Shell可以访问API:


   
   
clh@marseille:~$ groovysh
Groovy Shell (2.5.3, JVM: 1.8.0_212)
Type ':help' or ':h' for help.
----------------------------------------------------------------------------------------------------------------------------------
groovy:000> import groovy.json.JsonSlurper
===> groovy.json.JsonSlurper
groovy:000> result = (new JsonSlurper()).parse(
groovy:001>     new InputStreamReader((new URL('https://api.exchangerate-api.com/v4/latest/INR')).newInputStream())
groovy:002> )
===> [base:INR, date:2019-04-26, time_last_updated:1556236800, rates:[INR:1, AUD:0.020343, BRL:0.056786, CAD:0.019248, CHF:0.014554, CNY:0.096099, CZK:0.329222, DKK:0.095497, EUR:0.012789, GBP:0.011052, HKD:0.111898, HUF:4.118615, IDR:199.61769, ILS:0.051749, ISK:1.741659, JPY:1.595527, KRW:16.553091, MXN:0.272383, MYR:0.058964, NOK:0.123365, NZD:0.02161, PEN:0.047497, PHP:0.744974, PLN:0.054927, RON:0.060923, RUB:0.921808, SAR:0.053562, SEK:0.135226, SGD:0.019442, THB:0.457501, TRY:0.084362, TWD:0.441385, USD:0.014255, ZAR:0.206271]]
groovy:000>

由于对URL执行了Groovy JSON slurper,因此返回了相同的JSON负载。 当然,由于这是Groovy,因此JSON会转换为Map,因此您可以执行以下操作:


   
   
groovy:000> println result.base
INR
===> null
groovy:000> println result.date
2019-04-26
===> null
groovy:000> println result.rates.CAD
0.019248
===> null

就是这样!

您是否使用ExchangeRate-API或类似服务? 在评论中分享您如何使用汇率数据。

翻译自: https://opensource.com/article/19/5/exchange-rate-data

 类似资料: