实践中的货币 - OutSystems Fixer.io API 封装器





0/5 (0投票)
在本文中,我将提出一系列使用 Fixer API 的可能性,以支持一套支持多货币的场景。
大家好!我很高兴与大家分享与 OutSystems 平台进行的精彩集成。本次演示,我们将集成 Fixer,一个简单轻量的 API,用于获取当前和历史外汇汇率。
那么,实践中的货币,嗯?如果你在想,答案是肯定的:本文的标题灵感来自我个人喜欢的一本书《软件架构实践》。这是一本好书,你应该看看。它不是一本常规的“从头读到尾”的书,但包含关于质量属性和实现这些属性的策略的非常有趣的话题。如果你对软件架构感兴趣,我认为值得一看。
让我们回到主题。正如你可能已经知道的,OutSystems 支持多语言和多租户。但是……多货币呢?是的,OutSystems 不支持多货币,至少不是直接支持。明确地说,我们不会为你的多货币需求创建一刀切的解决方案。我将提出一系列使用 Fixer API 的可能性,以支持一套场景。
现在,至关重要的问题:什么场景?
在进入场景列表之前,我想对主题做一个简要介绍,并澄清一组现在将非常非常常见的术语。
那么,什么是货币?
根据“货币”一词最具体的用法(源自中古英语:curraunt,“流通中”,源自拉丁语:currens, -entis),指的是在实际使用或作为交易媒介流通中的任何形式的货币,特别是流通的纸币和硬币。更普遍的定义是,货币是一个货币体系(货币单位)在普遍使用,尤其是在一个国家。根据这个定义,美元、英镑、澳元、欧元和俄罗斯卢布都是货币的例子。这些不同的货币被认为是价值储存手段,并在国际外汇市场上进行交易,外汇市场决定了不同货币的相对价值。在此意义上的货币由政府定义,每种类型都有有限的接受范围。
以上摘录自Wikipedia,免费的百科全书。但是,我们大多数人都清楚什么是货币——因为我们几乎每天都在使用它——对吧?因此,相关的问题——也是绝大多数人可能不知道的问题——是:为什么货币的价值会发生变化?
根据 Investopedia 的说法,有六个主要因素影响货币的价值。而且,再次强调,货币的价值不是绝对值,而是总是相对于不同货币的相对价值。截至 2018 年 8 月 21 日,一 (1) 欧元价值一美元十五美分 (1.15)。绝对价值将始终为 1——一个欧元永远是一个欧元。
这些主要因素是
- 通货膨胀差异
- 利率差异
- 经常账户赤字
- 公共债务
- 贸易条件
- 政治稳定和经济表现
可以在以下文章中找到对这些因素的全面描述以及更多信息:影响汇率的 6 个因素,来自 Investopedia。
现在我们已经了解了影响货币价值的因素的冰山一角,让我们来讨论一些在本文其余部分将广泛使用的术语。
- 符号:符号是给定货币的代码。EUR 是欧元的符号,USD 是美元的符号。
- 基准:计算值的基准货币/符号。如果欧元基准下的美元价值为 1.20,则意味着 1 欧元将获得 1.2 美元。
- EOD:日终。在本文的上下文中,EOD 值将是给定日期的参考值。
还记得那个至关重要的问题吗?所以:我们将每小时检索一组符号相对于一个基准的当前值。默认情况下,我们的基准是欧元。如果你需要另一个基准——比如你的业务以美元结算——我们可以
a) 从 API 检索新值
b) 使用通用基准计算值。
在可能的选项中,一个有潜在成本(API 限制),另一个……则不然。不仅如此,我们将通过提供一组函数来支持这两种情况:一个用于检索给定时间点的值——如果你处理的是多货币的金融交易,这很好——以及一个用于转换货币 A 为 B,使用基准 C——通常称为交叉汇率。
我不会讨论如何获取 API 密钥,因为,嗯……在 Fixer 的网站上非常简单明了。一旦你有了 API 密钥,你就可以开始集成可用的端点。
现在,技术细节。
Fixer “默认”提供了六个不同的端点:一个用于支持的符号,五个用于货币值本身。在这五个与货币相关的端点中,我们有一个用于最新值,一个用于历史值,一个用于货币转换,一个用于两个日期之间的货币波动,还有一个用于时间序列值。
虽然前三个的目的似乎非常清楚,但我将对后两个端点做简要解释。以两个日期为例:1 月 1 日和 1 月 5 日。当你调用波动端点时,你将获得 1 月 5 日 EOD 值与 1 月 1 日 EOD 值之间的差值——所以,只有一个结果。如果你调用这两个日期的时序值,你将收到这五天内给定符号的每日 EOD 值——所以,有五个结果。当我们进行实现并查看响应时,这将更容易理解。
关于可用的端点,我想在此声明一个非常重要的事情:并非所有端点都包含在免费套餐中。免费套餐仅包含符号、最新和历史数据——这并非什么大问题,因为我们可以使用免费端点来获取与付费端点相关的数据,只要我们在免费套餐的限制内进行操作。这就是为什么当你查看 REST 集成时,你会看到两个“不同”的条目:一个名为 FixerFree,另一个名为 FixerPaid。它们各自包含相应的端点,而 BaseURL 属性是相同的。
集成
如前所述,我们将实现所有六个可用端点。所有端点的实现逻辑都将非常相似:我们获取完整的请求和响应,将其粘贴到 Service Studio,然后它就会自动创建所有结构的集成。我们将使用数据模型来存储所有信息来支持此集成。很简单,对吧?
嗯……不太是。让我解释一下,以符号端点为例。让我们向端点发出 GET 请求: http://data.fixer.io/api/symbols?access_key=<API KEY>。你会看到这样的结果
{
"success": true,
"symbols": {
"AED": "United Arab Emirates Dirham",
"AFN": "Afghan Afghani",
"ALL": "Albanian Lek",
"AMD": "Armenian Dram",
"ANG": "Netherlands Antillean Guilder",
"AOA": "Angolan Kwanza",
"ARS": "Argentine Peso",
"AUD": "Australian Dollar",
"AWG": "Aruban Florin",
"AZN": "Azerbaijani Manat",
"BAM": "Bosnia-Herzegovina Convertible Mark",
"BBD": "Barbadian Dollar",
"BDT": "Bangladeshi Taka",
"BGN": "Bulgarian Lev",
"BHD": "Bahraini Dinar",
"BIF": "Burundian Franc",
"BMD": "Bermudan Dollar",
"BND": "Brunei Dollar",
"BOB": "Bolivian Boliviano",
"BRL": "Brazilian Real",
"BSD": "Bahamian Dollar",
"BTC": "Bitcoin",
"BTN": "Bhutanese Ngultrum",
"BWP": "Botswanan Pula",
"BYN": "New Belarusian Ruble",
"BYR": "Belarusian Ruble",
"BZD": "Belize Dollar",
"CAD": "Canadian Dollar",
"CDF": "Congolese Franc",
"CHF": "Swiss Franc",
"CLF": "Chilean Unit of Account (UF)",
"CLP": "Chilean Peso",
"CNY": "Chinese Yuan",
"COP": "Colombian Peso",
"CRC": "Costa Rican Colón",
"CUC": "Cuban Convertible Peso",
"CUP": "Cuban Peso",
"CVE": "Cape Verdean Escudo",
"CZK": "Czech Republic Koruna",
"DJF": "Djiboutian Franc",
"DKK": "Danish Krone",
"DOP": "Dominican Peso",
"DZD": "Algerian Dinar",
"EGP": "Egyptian Pound",
"ERN": "Eritrean Nakfa",
"ETB": "Ethiopian Birr",
"EUR": "Euro",
"FJD": "Fijian Dollar",
"FKP": "Falkland Islands Pound",
"GBP": "British Pound Sterling",
"GEL": "Georgian Lari",
"GGP": "Guernsey Pound",
"GHS": "Ghanaian Cedi",
"GIP": "Gibraltar Pound",
"GMD": "Gambian Dalasi",
"GNF": "Guinean Franc",
"GTQ": "Guatemalan Quetzal",
"GYD": "Guyanaese Dollar",
"HKD": "Hong Kong Dollar",
"HNL": "Honduran Lempira",
"HRK": "Croatian Kuna",
"HTG": "Haitian Gourde",
"HUF": "Hungarian Forint",
"IDR": "Indonesian Rupiah",
"ILS": "Israeli New Sheqel",
"IMP": "Manx pound",
"INR": "Indian Rupee",
"IQD": "Iraqi Dinar",
"IRR": "Iranian Rial",
"ISK": "Icelandic Króna",
"JEP": "Jersey Pound",
"JMD": "Jamaican Dollar",
"JOD": "Jordanian Dinar",
"JPY": "Japanese Yen",
"KES": "Kenyan Shilling",
"KGS": "Kyrgystani Som",
"KHR": "Cambodian Riel",
"KMF": "Comorian Franc",
"KPW": "North Korean Won",
"KRW": "South Korean Won",
"KWD": "Kuwaiti Dinar",
"KYD": "Cayman Islands Dollar",
"KZT": "Kazakhstani Tenge",
"LAK": "Laotian Kip",
"LBP": "Lebanese Pound",
"LKR": "Sri Lankan Rupee",
"LRD": "Liberian Dollar",
"LSL": "Lesotho Loti",
"LTL": "Lithuanian Litas",
"LVL": "Latvian Lats",
"LYD": "Libyan Dinar",
"MAD": "Moroccan Dirham",
"MDL": "Moldovan Leu",
"MGA": "Malagasy Ariary",
"MKD": "Macedonian Denar",
"MMK": "Myanma Kyat",
"MNT": "Mongolian Tugrik",
"MOP": "Macanese Pataca",
"MRO": "Mauritanian Ouguiya",
"MUR": "Mauritian Rupee",
"MVR": "Maldivian Rufiyaa",
"MWK": "Malawian Kwacha",
"MXN": "Mexican Peso",
"MYR": "Malaysian Ringgit",
"MZN": "Mozambican Metical",
"NAD": "Namibian Dollar",
"NGN": "Nigerian Naira",
"NIO": "Nicaraguan Córdoba",
"NOK": "Norwegian Krone",
"NPR": "Nepalese Rupee",
"NZD": "New Zealand Dollar",
"OMR": "Omani Rial",
"PAB": "Panamanian Balboa",
"PEN": "Peruvian Nuevo Sol",
"PGK": "Papua New Guinean Kina",
"PHP": "Philippine Peso",
"PKR": "Pakistani Rupee",
"PLN": "Polish Zloty",
"PYG": "Paraguayan Guarani",
"QAR": "Qatari Rial",
"RON": "Romanian Leu",
"RSD": "Serbian Dinar",
"RUB": "Russian Ruble",
"RWF": "Rwandan Franc",
"SAR": "Saudi Riyal",
"SBD": "Solomon Islands Dollar",
"SCR": "Seychellois Rupee",
"SDG": "Sudanese Pound",
"SEK": "Swedish Krona",
"SGD": "Singapore Dollar",
"SHP": "Saint Helena Pound",
"SLL": "Sierra Leonean Leone",
"SOS": "Somali Shilling",
"SRD": "Surinamese Dollar",
"STD": "São Tomé and Príncipe Dobra",
"SVC": "Salvadoran Colón",
"SYP": "Syrian Pound",
"SZL": "Swazi Lilangeni",
"THB": "Thai Baht",
"TJS": "Tajikistani Somoni",
"TMT": "Turkmenistani Manat",
"TND": "Tunisian Dinar",
"TOP": "Tongan Paʻanga",
"TRY": "Turkish Lira",
"TTD": "Trinidad and Tobago Dollar",
"TWD": "New Taiwan Dollar",
"TZS": "Tanzanian Shilling",
"UAH": "Ukrainian Hryvnia",
"UGX": "Ugandan Shilling",
"USD": "United States Dollar",
"UYU": "Uruguayan Peso",
"UZS": "Uzbekistan Som",
"VEF": "Venezuelan Bolívar Fuerte",
"VND": "Vietnamese Dong",
"VUV": "Vanuatu Vatu",
"WST": "Samoan Tala",
"XAF": "CFA Franc BEAC",
"XAG": "Silver (troy ounce)",
"XAU": "Gold (troy ounce)",
"XCD": "East Caribbean Dollar",
"XDR": "Special Drawing Rights",
"XOF": "CFA Franc BCEAO",
"XPF": "CFP Franc",
"YER": "Yemeni Rial",
"ZAR": "South African Rand",
"ZMK": "Zambian Kwacha (pre-2013)",
"ZMW": "Zambian Kwacha",
"ZWL": "Zimbabwean Dollar"
}
}
看起来输出很简单,对吧?错了!当你使用 OutSystems 的默认功能导入 REST 方法/端点时,你会得到图 2 所示的内容。比如,一个结构中有 168 个属性。正如 Jesse Ventura 所说,我没有时间去遍历一个我必须手动迭代的结构的 168 个属性。另外,在有人提到“也许 ardoJSON 可以解决问题”之前,我要说一次,而且只说一次
**是的,我百分之百确定 Jesse Ventura 曾这么说过。
那么,我做了什么?好吧,除了 Convert 端点之外,所有端点的输出都是纯文本。然后,我将使用一个很酷的(自定义)C# 扩展来解析输出,并为 OutSystems 提供一个“可扩展”的响应版本。尽管看到了低代码平台的种种好处,我仍然喜欢“敲几行代码”——灵感来自 Carlos Carvalhal 的“把所有的肉都放到烧烤架上”。这可能也是我准备了新的和旧的阅读材料以备将来几天的原因——尽管这些书都不是 OutSystems 人“推荐”阅读的。
由于我不想让本文过长,我将快速总结开发过程
- 我们将从 Fixer 检索完整的 JSON 输出
- 我们将使用一个工具从 JSON 输出生成 C# 类。(相信我,这很有趣)
- 我们将使用 Integration Studio 来实现这些方法,以便我们可以在 OutSystems 中接收数据。
我不会深入探讨“如何将 REST 端点导入 OutSystems”。互联网上有很多资源,而且事实上,这非常简单,你应该先尝试自己动手。
到目前为止,我们已经将端点集成到了 Service Studio。因此,让我们进入有趣的部分:在 OutSystems 扩展中处理响应。如上所述,我使用了一个工具从 JSON 输出生成 C# 类。如果你在 Google 上搜索json to c# class,你看到的第一个结果可能是 http://json2csharp.com。虽然这完全没问题,但底部有一个名为 Quicktype 的选项。我强烈推荐使用 Quicktype。为什么?
我将引导你完成我的旅程,并使用 json2csharp 从 JSON 对象生成 C# 类。对于 Symbols 端点,我们得到这个
public class Symbols
{
public string AED { get; set; }
public string AFN { get; set; }
public string ALL { get; set; }
public string AMD { get; set; }
public string ANG { get; set; }
public string AOA { get; set; }
public string ARS { get; set; }
public string AUD { get; set; }
public string AWG { get; set; }
public string AZN { get; set; }
public string BAM { get; set; }
public string BBD { get; set; }
public string BDT { get; set; }
public string BGN { get; set; }
public string BHD { get; set; }
public string BIF { get; set; }
public string BMD { get; set; }
public string BND { get; set; }
public string BOB { get; set; }
public string BRL { get; set; }
public string BSD { get; set; }
public string BTC { get; set; }
public string BTN { get; set; }
public string BWP { get; set; }
public string BYN { get; set; }
public string BYR { get; set; }
public string BZD { get; set; }
public string CAD { get; set; }
public string CDF { get; set; }
public string CHF { get; set; }
public string CLF { get; set; }
public string CLP { get; set; }
public string CNY { get; set; }
public string COP { get; set; }
public string CRC { get; set; }
public string CUC { get; set; }
public string CUP { get; set; }
public string CVE { get; set; }
public string CZK { get; set; }
public string DJF { get; set; }
public string DKK { get; set; }
public string DOP { get; set; }
public string DZD { get; set; }
public string EGP { get; set; }
public string ERN { get; set; }
public string ETB { get; set; }
public string EUR { get; set; }
public string FJD { get; set; }
public string FKP { get; set; }
public string GBP { get; set; }
public string GEL { get; set; }
public string GGP { get; set; }
public string GHS { get; set; }
public string GIP { get; set; }
public string GMD { get; set; }
public string GNF { get; set; }
public string GTQ { get; set; }
public string GYD { get; set; }
public string HKD { get; set; }
public string HNL { get; set; }
public string HRK { get; set; }
public string HTG { get; set; }
public string HUF { get; set; }
public string IDR { get; set; }
public string ILS { get; set; }
public string IMP { get; set; }
public string INR { get; set; }
public string IQD { get; set; }
public string IRR { get; set; }
public string ISK { get; set; }
public string JEP { get; set; }
public string JMD { get; set; }
public string JOD { get; set; }
public string JPY { get; set; }
public string KES { get; set; }
public string KGS { get; set; }
public string KHR { get; set; }
public string KMF { get; set; }
public string KPW { get; set; }
public string KRW { get; set; }
public string KWD { get; set; }
public string KYD { get; set; }
public string KZT { get; set; }
public string LAK { get; set; }
public string LBP { get; set; }
public string LKR { get; set; }
public string LRD { get; set; }
public string LSL { get; set; }
public string LTL { get; set; }
public string LVL { get; set; }
public string LYD { get; set; }
public string MAD { get; set; }
public string MDL { get; set; }
public string MGA { get; set; }
public string MKD { get; set; }
public string MMK { get; set; }
public string MNT { get; set; }
public string MOP { get; set; }
public string MRO { get; set; }
public string MUR { get; set; }
public string MVR { get; set; }
public string MWK { get; set; }
public string MXN { get; set; }
public string MYR { get; set; }
public string MZN { get; set; }
public string NAD { get; set; }
public string NGN { get; set; }
public string NIO { get; set; }
public string NOK { get; set; }
public string NPR { get; set; }
public string NZD { get; set; }
public string OMR { get; set; }
public string PAB { get; set; }
public string PEN { get; set; }
public string PGK { get; set; }
public string PHP { get; set; }
public string PKR { get; set; }
public string PLN { get; set; }
public string PYG { get; set; }
public string QAR { get; set; }
public string RON { get; set; }
public string RSD { get; set; }
public string RUB { get; set; }
public string RWF { get; set; }
public string SAR { get; set; }
public string SBD { get; set; }
public string SCR { get; set; }
public string SDG { get; set; }
public string SEK { get; set; }
public string SGD { get; set; }
public string SHP { get; set; }
public string SLL { get; set; }
public string SOS { get; set; }
public string SRD { get; set; }
public string STD { get; set; }
public string SVC { get; set; }
public string SYP { get; set; }
public string SZL { get; set; }
public string THB { get; set; }
public string TJS { get; set; }
public string TMT { get; set; }
public string TND { get; set; }
public string TOP { get; set; }
public string TRY { get; set; }
public string TTD { get; set; }
public string TWD { get; set; }
public string TZS { get; set; }
public string UAH { get; set; }
public string UGX { get; set; }
public string USD { get; set; }
public string UYU { get; set; }
public string UZS { get; set; }
public string VEF { get; set; }
public string VND { get; set; }
public string VUV { get; set; }
public string WST { get; set; }
public string XAF { get; set; }
public string XAG { get; set; }
public string XAU { get; set; }
public string XCD { get; set; }
public string XDR { get; set; }
public string XOF { get; set; }
public string XPF { get; set; }
public string YER { get; set; }
public string ZAR { get; set; }
public string ZMK { get; set; }
public string ZMW { get; set; }
public string ZWL { get; set; }
}
public class RootObject
{
public bool success { get; set; }
public Symbols symbols { get; set; }
}
看到结果了吗?我一点也不懂 C#,但我很想知道:如何将这一组元素转换为键值对列表,知道键就是字段本身的名称?
你好,你听说过反射吗? 对于不了解的人来说,反射对程序员来说就像是鬼怪对孩子一样。我可能有点夸张——除非你尝试用 CLOS 进行元编程:那样的话,鬼怪就像饼干怪兽一样邪恶。
反射很棒,但也有问题。使用反射的性能成本不可忽视。幸运的是,使用 Quicktype,我得到了这个精巧的版本
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using OutSystems.NssFixerParser.Integrations;
//
// var getSymbols = GetSymbols.FromJson(jsonString);
namespace OutSystems.NssFixerParser.Integrations
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class GetSymbols
{
[JsonProperty("success")]
public bool Success { get; set; }
[JsonProperty("symbols")]
public Dictionary<string, string> Symbols { get; set; }
}
public partial class GetSymbols
{
public static GetSymbols FromJson(string json)
{
return JsonConvert.DeserializeObject<GetSymbols>(json, OutSystems.NssFixerParser.Integrations.Converter.Settings);
}
}
public static class Serialize
{
public static string ToJson(this GetSymbols self)
{
return JsonConvert.SerializeObject(self, OutSystems.NssFixerParser.Integrations.Converter.Settings);
}
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
重要提示:当使用 Quicktype 从 JSON 对象生成 C# 类以供 OutSystems 使用时,请确保选择 C# 版本为 V5。默认情况下,选择 V6,它将无法编译。注意:在与其他 MVP 的一次聊天中,这可能与 MSBuild 有关。我将进一步研究并相应更新帖子。
有些相关的注释:如果你使用 Quicktype 生成的多个类,其中包含公共元素(如 Error 结构),只需将这些类移动到单独的文件中。然后可以从生成代码中删除它们,只要你已正确引用所有内容,就不会出现错误。
根据上面的注释,我将 internal static class Converter, public static class Serialize
和 Error
类(图 6 未显示)移到了单独的文件中,最终结果如图 7 所示。这样做,我们将有四个类用于五个端点——Convert 端点不在此方法考虑范围内——即 Converter、Serialize 和 Error 类(通用类)。如果你擅长数学,你可能会想:等等,什么?五个端点对应四个类?
是的,这是因为历史汇率和最新汇率具有相同的输出结构。那么,我们能做什么?没错,我们可以为它们使用相同的代码。这样就节省了工作。
现在,让我们进入实际操作。在 Integration Studio 中,我们将创建一个具有图 9 所示配置的扩展。
注意:在有人询问之前,目前没有 Java 版本。未来可能会有,但可能性很小。
然后,我们将定义一个操作,并具有以下参数——如图 10 所示
- JSONString(输入)
- Success(输出)
- Symbols — 键值对列表(输出)
- Error — 通用错误结构(输出)
现在我们已经定义了操作并更新了扩展代码,是时候使用我们生成的类了
/// <summary>
///
/// </summary>
/// <param name="ssJSONString"></param>
/// <param name="ssSuccess"></param>
/// <param name="ssSymbols"></param>
/// <param name="ssError"></param>
public void MssParse_GetSymbols(string ssJSONString, out bool ssSuccess,
out RLKeyPairStructureRecordList ssSymbols,
out RCErrorRecord ssError)
{
ssSuccess = false;
ssSymbols = new RLKeyPairStructureRecordList();
ssError = new RCErrorRecord(null);
GetSymbols getSymbols = GetSymbols.FromJson(ssJSONString);
if (getSymbols.Success)
{
foreach (String ISOCode in getSymbols.Symbols.Keys)
{
RCKeyPairStructureRecord rec = new RCKeyPairStructureRecord();
rec.ssSTKeyPairStructure.ssKey = ISOCode;
rec.ssSTKeyPairStructure.ssValue = getSymbols.Symbols[ISOCode];
ssSymbols.Append(rec);
}
ssSuccess = true;
}
else
{
ssSuccess = false;
ssError.ssSTError.ssCode = getSymbols.Error.Code.ToString();
ssError.ssSTError.ssInfo = getSymbols.Error.Info;
ssError.ssSTError.ssType = getSymbols.Error.Type;
}
} // MssParse_GetSymbols
上面可以看到我们在做什么。这是所有操作的通用过程。不同之处在于复杂性或字段的数量。如果你愿意,可以随意查看扩展的源代码,并告诉我是否有任何问题、疑虑或建议。再次强调,分享即关怀。
因此,除了常规的变量初始化之外,我们将 JSON 字符串反序列化为 GetSymbols
对象(第 16 行),并验证请求是否成功。如果成功,我们将遍历字典并创建一个 KeyPairStructureRecord
——我不知道为什么完整名称是 RC KeyPairStructureRecord
,因为最佳实践告诉我们记录名称应以 RC 开头——然后将其添加到列表中。
如果请求不成功,我们将填充我们的错误结构。简单。
我在这里加一句个人评论:当我开始为这个组件工作时,我非常想写一篇关于 C# 反射的文章,这样你们就会认为我是一个超级厉害的 C# 程序员。但这就是软件开发的酷之处:你认为的事情,它们改变得如此之快和容易(#Agile)。而这,我的朋友们,就是我们工作的魅力——如果我以后转行去做电视新闻主播,那将是我的结尾语。
但是……我们该如何使用它呢?
创建一个组件并写一篇关于它的文章,如果不展示它的工作方式,那就没有意义了。所以,如果你还记得以前的文章,我们已经有一个控制面板,它将是这个组件的绝佳载体。
总而言之——并创建一个场景——我们已经有一个控制面板,显示我们网关处理的最新付款。这些最新付款可能有不同的货币,但我们的业务只以欧元结算。
在引用的文章的图 17(本文图 12)中,你有以下图片
在右上角,我们有一个 CardSimple,显示“过去 30 天内的热门支付”。虽然有点模糊,但我们可以看到有欧元、日元和其他货币的支付。现在,让我们修改这个 CardSimple,确保我们显示的是交易发生当日的转换值。原始值将以欧元为基准进行转换。这有一个“许可”原因,我稍后会解释。
为了简单起见,我将使用一个可用的函数——CalculateConversion
。对于 ListRecords 小部件中的每个项目,我将调用该函数,并计算结果。该函数行为如图 13 所示。
此函数接收以下输入参数:BaseCurrency(文本)、DestinationCurrency(文本)、Amount(货币)、Date(日期)和一个输出参数:Value(货币)。现在,一步一步来
- 我们检查在给定日期是否有可用的货币值(GetConversion 聚合)。如果存在,我们返回该值。
- 如果不存在,我们尝试进行交叉货币转换。如果两个值在提到的日期都可用,我们将返回计算后的值。计算方式如下——为便于说明,元素已缩短。
Amount / (GetSourceCurrency.Value / GetDestinationCurrency.Value)
- 如果值不可用,我们将执行 API 请求,如果成功,将返回汇率。由于我们只请求一个值,我们可以立即将其映射到输出。
然后,在 Card 小部件中的 ListRecords
中,我们将这个添加到我们的表达式中——如图 14 所示。由于使用了 FormatCurrency
函数来格式化转换后的金额,所以它有点“臃肿”。另外,由于我们以欧元为基准,我们不需要计算小数位数。请参考上一篇文章以理解这个概念。
我们有了第一个 FormatCurrency
,现在我们添加了文本部分“ (EUR: XXX)”,其中 XXX 将使用 CalculateConversion 函数计算。只是一个重要说明:请注意,在调用 CalculateConversion 函数时,我没有使用 DestinationCurrency
参数?这是因为我们将 DestinationCurrency
参数映射到了服务调用中的 Base 参数。由于我们使用免费套餐,因此无法在 API 调用中使用 Base 参数,默认情况下为 EUR。如果你至少拥有基础会员资格,就可以使用它。
这是最终结果——与谷歌在相应日期的值完全匹配
就这样,各位!该组件已在 OutSystems Forge 上提供,网址为 https://www.outsystems.com/forge/component/4122/fixer-io-api/。
在结束之前,我将尝试一些新的事情。我正在研究发布赞助文章的可能性。如果你(或你的公司)有一些闲钱,并希望赞助任何文章或关于特定主题的文章,请通过 hello@armandogom.es 给我留言。明确说明:我真的很喜欢写作和创作新内容,所以我不会把钱留给自己。
因此,任何赞助文章的所有利润都将捐赠给慈善机构。
有关此事的更多详情,请通过上述电子邮件、Twitter 或 LinkedIn 与我联系。
结束语 - 就是这样,各位!组件已在 OutSystems Forge 上提供,网址为 https://www.outsystems.com/forge/component/4122/fixer-io-api/。