“Currencies in Practice” — or the story of implementing a currency converter in OutSystems

Armando Gomes
ITNEXT
Published in
15 min readAug 28, 2018

--

Hello everyone! I’m back again with another awesome integration with the OutSystems platform. This time, we’ll be integrating Fixer, a simple and lightweight API for current and historical foreign exchange (forex) rates.

Before going any further, I would like to publicly thank Andreas and all the Fixer team for the support they have given in order to build this integration. Thank you very much.

Also, before going into the technicalities of the currencies, the Fixer API and how to use it, I would like to make two remarks:

  • The first one is that I’ve been named an OutSystems MVP! I’m so proud of the achievement and I would like to thank everyone — and OutSystems, obviously! — that I’ve crossed paths with. Without you, none of this would be possible.
  • The second one is to assure that I’ll do my best in order to make sure I’m worth the recognition. I’m proud of being part of this community and, you know, sharing is caring!

Feel free to come across my website — which is in constant evolution — and see what I’ve done and, more important, what can I do for you. Also, all the feedback is appreciated! If you can’t find what you’re looking for, feel free to contact me so I can help you in the best way possible.

So let’s stop talking about me and let’s start talking about you. Or, in this case, something that you can get your hands on, completely free!

FREEBIE TIME

As of now, you’re probably aware that OutSystems has been considered an Unicorn and, since they are a bunch of nice guys, they are giving back to the developers — like, who needs 360 million, anyway? Protip: yours truly. Ok, but this is not about me. This is about Neo. As such, you have the unique opportunity to earn a very-limited handcrafted Neo figure. Sounds awesome, right? And the only thing you need to do is to click on the link below and register with your email. More detailed instructions are present on the blog post, but you’ll quickly get the hang of it.

Disclaimer: yes, if you go through this link, I’ll go up in the ranks and I’ll get my hands on a Neo first. I’ll post some pictures of it, though.

In the unlikely case that you’re like me and you’re wondering something in the likes of: “why action figures when they could spend all their money on pizzas and cakes?”, I also have an answer for that: Meetups. Join the next one.

The show must go on.

Now that I’ve spoke about me — goddamn narcissist and about something that you can win, it’s time to get back to our main subject — an OutSystems wrapper for the Fixer.io API.

So, currencies in practice, huh? If you’re wondering, the answer is yes: the title of this article was inspired in a book that I personally enjoy named Software Architecture in Practice. It’s a good book, you should take a look. It’s not a regular “read from cover to cover” but has very interesting topics about quality attributes and tactics to achieve those same attributes. If you’re interested in the software architecture subject, I think it’s worth a look.

Let’s get back to the subject. As you might know by now, OutSystems supports multi-language and multi-tenancy. But… what about multi-currency? Yes, OutSystems doesn’t support multi-currency, at least directly. And, to be clear, we are not going to create a one-size-fits-all solution for your multi-currency needs. I’m going to propose a list of possibilities using Fixer’s API in order to support a set of scenarios.

And now, the almighty question: which scenarios?

Before going into the scenario list, I would like to make a quick introduction to the subject and clarify a set of terms that will be very, very common from now on.

So, what is a currency?

A currency (from Middle English: curraunt, “in circulation”, from Latin: currens, -entis), in the most specific use of the word, refers to money in any form when in actual use or circulation as a medium of exchange, especially circulating banknotes and coins. A more general definition is that a currency is a system of money (monetary units) in common use, especially in a nation. Under this definition, US dollars, British pounds, Australian dollars, European euros and Russian ruble are examples of currency. These various currencies are recognized stores of value and are traded between nations in foreign exchange markets, which determine the relative values of the different currencies. Currencies in this sense are defined by governments, and each type has limited boundaries of acceptance.

The excerpt above was taken from Wikipedia, the free encyclopedia. But, most of us are pretty aware of what a currency is — since we use it pretty much everyday — , right? As such, the relevant question — and that the vast majority might not know — is: why does a currency value change?

According to Investopedia, there are six major factors that influence the value of a currency. And, again, the value of the currency is not an absolute value but always a relative value against a different currency. As of Aug. 21st, 2018, one (1) EURO is worth one United States Dollar and fifteen cents (1.15). The absolute value will always be 1 — one EURO will always be one EURO.

Those major factors are:

  • Differentials in Inflation
  • Differentials in Interest Rates
  • Current Account Deficits
  • Public Debt
  • Terms of Trade
  • Political Stability and Economical Performance

A comprehensive description of these factors along with more information can be seen in the following article: 6 factors that influence exchange rates, from Investopedia.

Now that we’ve seen the tip of the iceberg in terms of the factors that influence currency values, let’s discuss some terms that will be wildly used along the remaining of the article.

  • Symbol: symbol is the code of a given currency. EUR is the symbol for EURO while USD is the symbol for United States Dollar.
  • Base: The base currency/symbol to which the value is calculated against. If the USD value with an EUR base is 1.20, means that €1 will get you $1.2.
  • EOD: end-of-day. In the context of this article, the EOD value will be the reference value for a given day.

Remember the almighty question about the scenarios? So: we are going to retrieve, on an hourly basis, the current value of a set of symbols against a base. By default our base will be EUR. If you need another base — let’s say that your business runs on US Dollars — , we can either:

a) retrieve the new value from the API

b) calculate the value using a common base.

In terms of the possible options, one has potential costs (API restriction), the other… not so much. Not only this, but we’ll support both by providing a set of functions to retrieve a value during a given point in time — which is a good thing if you deal with multi-currency on your financial transactions — and to convert from Currency A to B using a Base C — mostly known as cross-currency rate.

I’m not going to discuss how to get an API key since, well… it’s pretty straightforward on Fixer’s website. Once you have your API key, you can start integrating the available endpoints.

Now, the technicalities.

Fixer provides, by “default”, six different endpoints: one for supported symbols and five for the currency values themselves. On these five currency-related endpoints, we have one for the latest values, one for historical values, one for currency conversion, one for currency fluctuation between two dates and one for time-series values.

While the first three seem very clear to their purpose, let me give a brief explanation on the last two endpoints. Consider, just for the sake of this example, two dates: January 1st and January 5th. When you invoke the fluctuation endpoint, you’ll retrieve the difference between the EOD value of Jan 5th and Jan 1st — so, one result only. If you invoke the time-series value for these two dates, you’ll receive the daily EOD value of the given symbols between these five days — so, five results. Once we get to the implementation and the response itself, this will be easier to understand.

Regarding the available endpoints, I would like to make a very important statement here: not all endpoints are included in the free tier. Only Symbols, Latest and Historical data are included in the free tier — which is not that problematic, since we can use the free endpoints to obtain the data related to the paid ones, as long as we do it within the limits of the free tier itself. That is the reason why, when you take a look at the REST integrations, you’ll see two “different” entries: one named FixerFree and the other named FixerPaid. Each of them contains the respective endpoints while the BaseURL property is the same.

The integration

As discussed previously, we’ll implement all the six endpoints available. The implementation logic will be pretty much similar for all the endpoints: we get the full request and the response, we paste into Service Studio and then it just creates the integrations with all the structures. We’ll support this integration with a data model to store all the information. Simple, right?

Well… not so much. And let me explain why, using the Symbols endpoint. Let’s do a GET request to endpoint: http://data.fixer.io/api/symbols?access_key=<API KEY>. This is what you’ll see as a result:

Figure 1 — Symbol endpoint output
Figure 2 — Generated structures.

Seems like a simple output, right? WRONG! When you use OutSystems default capabilities to import REST method / endpoint, you’ll get what’s depicted on Figure 2. Like, 168 attributes on a structure. As Jesse Ventura would say, I ain’t got time to go over 168 attributes on a structure that I would have to, well, iterate manually**. Also, before anyone hits me with something like “probably ardoJSON could do the trick”, I’m going to say this once AND ONLY ONCE:

Figure 3 — But it’s a different love, mate!

** Yes, I’m 100% sure Jesse Ventura said this.

So, what did I do? Well, the output of every endpoint except one — Convert — will be plain text. I’ll then use a cool — and custom — C# extension to parse the output and provide OutSystems with a “scalable” version of the response. Despite seeing all the benefits of the low-code platforms, I still like to “hit some lines of code” — inspired by Carlos Carvalhal’s “Put all the meat on the barbecue”. And probably that’s why I got some new and old reading materials ready for the next days — despite none of these books being “recommended” readings by OutSystems people.

Figure 4 — Reading materials. And yes, those are ball cans. Regarding the last one, my Data Structures and Algorithms teacher would be proud, I’m sure.

Since I don’t want to make this article unnecessarily long, let me quickly round up the development process:

  • We’ll retrieve the full JSON output from Fixer
  • We’ll use a tool to generate a C# class from the JSON output. (Funny part, believe me)
  • We’ll use Integration Studio to implement the methods so we can receive our data in OutSystems.

I’m not going to delve into “how to import REST endpoints into OutSystems”. There are lots of resources on the internet and, in fact, it’s so easy that you should try first, all by yourself.

So far we have our endpoints integrated in the Service Studio. As such, let’s move to the funny part: processing the response on the OutSystems extension. As stated above, I’ve used a tool to generate a C# class from a JSON output. If you Google json to c# class, the first hit you’ll see is, probably, http://json2csharp.com. And while this is totally fine, there’s an option on the bottom called Quicktype. I strongly recommend using Quicktype. Why?

I’m going to guide you through my journey and I’ll generate a C# class from a JSON object using json2csharp. For the Symbols endpoint, we get this:

Figure 5 — json2csharp output.

See the result? I’m not a C# expert at all but I wondered: how would I convert this set of elements into a Key-Pair list, knowing the Key is the name of the field itself?

Hello, haaaaave you met Reflection? For those who don’t know, Reflection is for programmers what the Boogeyman is for kids. I might be exaggerating a bit here — unless you try to do meta-programming with CLOS: in that case, the Boogeyman is as evil as the Cookie Monster.

Reflection is awesome, but it is also problematic. The performance cost of using reflection is non-negligible. Luckily, using Quicktype, I got this neat version:

Figure 6 — Quicktype output

Relevant note: when using Quicktype to generate C# classes from JSON objects for OutSystems use, make sure the C# version you select is V5. By default, V6 is selected and that won’t compile. Note: on a chat with other fellow MVP’s, it could be related to the MSBuild. I’ll take a further look and update the post accordingly.

Somewhat-relevant note: if you use multiple classes generated by Quicktype that have elements in common — like an Error structure — , just move those classes into separate files. You can then remove them from the generated code and, as long as you have everything referenced, no errors will appear.

Figure 7— Extension structure.

Based on the previous note, I’ve moved the internal static class Converter, public static class Serialize and the Error class — which is not shown on figure 6 — into separate files, with the end result being something like Figure 7. Doing this, we’ll have four classes for five endpoints — Convert endpoint is not considered for this approach — , the Converter, the Serialize and the Error classes (generics). If you’re good with math, you’re wondering: wait, what? Four classes for five endpoints?

Yes, and that’s because Historical and Latest rates have the same output structure. So, what can we do? That’s right, we can use the same code for it. Saving work already.

Figure 8 — We’re all good with math. Source: Amazon.ca.

Let’s now move into the action itself. On the Integration Studio, we’ll create an extension with the configurations shown on Figure 9.

Figure 9 — Extension configuration.

Note: before anyone asks, a Java version is not available at the moment. It might happen in the future, although very unlikely.

Then we’ll define an action and the following parameters — as shown on Figure 10:

  • JSONString (Input)
  • Success (Output)
  • Symbols — The key-pair list (Output)
  • Error — generic error structure (Output)
Figure 10— Integration Studio with Parse_GetSymbols open.

Now that we have defined our action and updated our extension code, it’s time to use our generated classes:

Figure 11 — Parse_GetSymbols method body.

Above you can see what we are doing. This is a common procedure across all actions. What differs from one to others, is the complexity and/or number of fields. If you want, feel free to take a look at the extension’s source code and let me know if you have any question, concern or suggestions. Once again, sharing is caring.

So, besides the regular initialization of variables, we deserialize our JSON string into a GetSymbols object (line 16) and we validate if the request was successful. If so, we iterate over our dictionary and create a KeyPairStructureRecord — I wonder why the full name is RCKeyPairStructureRecord since best practices tell us to start a record name with RC… — that we’ll append to the list.

If the request was not successful, we fill our error structure. Simple.

I’m going to add a personal comment here: when I started working for this component, I was eager to write an article all about Reflection with C#, so you would think I was a SUPER DUPER ÜBER C# Programmer. But this is the cool thing about software development: the things you think, they change so quickly and easily (#Agile). And that, my friends, is the beauty of our job — if I ever change career to a TV News anchor, that will be my closing line.

But… how do we use it?

It’s worth nothing creating a component and write an article about it if you don’t show it working. So, if you recall from a previous article, we already have a Control Panel that would be a great candidate for this component.

So, summing up — and creating a scenario — , we already have a control panel that shows us the latest payments made through our gateway. Those latest payments can have different currencies but our business only runs on EUROS.

On the Figure 17 of the referenced article (Figure 12 on this one), you have the following image:

Figure 12 — Adyen Control Panel

On the top right corner, we have a CardSimple with the Top Payments in the last 30 days. It’s hard to see, but we have payments in EURO, YEN and others. Let’s now change this CardSimple and make sure we show the conversion value for the day that the transaction took place. The original value will be converted against EURO. This has a “licensing” reason, that I’ll explain later.

For the sake of simplicity, I’m going to use one of the available functions — CalculateConversion. For each item on the ListRecords widget, I’ll invoke the function and the result will be computed. The function behavior is the shown on Figure 13.

Figure 13 — CalculateConversion function.

This function receives the following input parameters: BaseCurrency (Text), DestinationCurrency (Text), Amount (Currency), Date (Date) and one output parameter: Value (Currency). Now, step by step:

  • We check if a currency value for the given date is already available (GetConversion aggregate). If it exists, we return the value.
  • If doesn’t exist, we try to do a cross-currency conversion. If both values are available for the mentioned date, we return the computed value. The calculation is done the following way — elements shortened on purpose.

Amount / (GetSourceCurrency.Value / GetDestinationCurrency.Value)

  • If the values are not available, we execute a request to the API that, if successful, will return the Rate. Since we’re just requesting one value, we can immediately map to the output.

Then, on the ListRecords present on the Card widget, we’ll add this to our expression — as shown on Figure 14. It’s a bit “bloated” due to the usage of the FormatCurrency function to the converted amount. Also, since we’re using EURO as a base, we don’t need to do any calculation of decimal places. Refer to the previous article in order to understand this concept.

Figure 14 — ListRecords expression.

We had the first FormatCurrency and now we added the text part “ (EUR: XXX)”, in which the XXX will be computed using the CalculateConversion function. Just one important note: see that I didn’t use the DestinationCurrency parameter when invoking the CalculateConversion function? This is because we’re mapping the DestinationCurrency parameter to the Base parameter on the service invocation. Since we’re using the free tier, we can’t use the base parameter on the API calls and, by default, it will be EUR. If you have, at least, the basic membership, you can use it.

And here’s the final result — which is a perfect match with Google’s value at the corresponding day:

Figure 15 — End result on the UI.

And that’s all, folks! The component is already available at OutSystems Forge at https://www.outsystems.com/forge/component/4122/fixer-io-api/.

Before finishing, I’m going to try something new. I’m looking into the possibility of publish sponsored articles. If you (or your company) have some money to spare and would like to sponsor any article or about a specific subject, please drop me a note through hello@armandogom.es. And, just to be clear on this: I really enjoy writing and creating new contents so I won’t keep the money for myself.

As such, all the profits of any sponsored article will be donated to charity.

For more details on this, ping me here, through the email above, Twitter, or LinkedIn.

Take care.

_________________________________________

Quicktype: https://quicktype.io

Fixer: https://fixer.io/

Fixer.io API: https://www.outsystems.com/forge/component/4122/fixer-io-api/

--

--

Founder of Volitional Software. OutSystems MVP. Reincarnation of the Cookie Monster. Proud owner of six fishes and two cats. https://www.volitionalsoftware.com