Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

The Currencies is a microservice, which provides the latest exchange rates of all existing currencies using the gRPC calls

chutommy/currencies

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Currencies

The Currencies is a microservice, which uses gRPC technology. It supports both unary and bidirectional streaming calls, which allows data update every 6 seconds. The service provides the latest market exchange rates of all currencies from all country. When an error occurs, it handles it in a non-fatal way with an error message.

The whole service is containerized using a Docker engine and the service can be easily launched and deployed with the pre-prepared make commands in the Makefile.

The Currencies obtains all necessary data from the Business Insider website. The algorithm does not infringe any copyrights nor the website robots exclusion protocol.

Installation

Requirements

Linux/Mac

The installation process on the Windows machines would be slightly different.

$ git clone https://github.com/chutommy/currencies.git     # download repository
$ cd currencies               # move to repository dir
$ make build                  # build docker image
$ make run                    # initialize service

Supported currency codes

BTG KZT GMD NMR PEN ARDR DCR FUN REQ IRR
QSP ANT CVE UAH MCO PYG BTM DOP NGN QTUM
SDG XRP CVC ICX LBC VTC XVG COP CZK SCR
GNO KMF NXT IDR PAB BSV BTS OMG PPT BIF
MKD XEM HRK NET UYU INR MAD RLC HKD LAK
BCC BZD EUR GBP MYR BTC GIP LRC NEO NULS
STX AFN DATA ETH CND GRID LKR TNT ADA DRGN
LINK PKR PLN RWF SYS CNY SNT WTC XMR ETC
KHR LRD LTC LYD SOS THB MMK USD NPR AED
ENJ GTQ AION CNX XAF BGN DTR MONA RCN BAT
BOB TOP UTK BYN GNT TJS WAVES KCS LEND MGA
REP ZRX ARK ISK MANA STORJ GBYTE KMD NIO HTG
SZL AUD EOS LA TWD DZD SVC JPY KNC MAID
PIVX SGD USDT CNH ELF GRS MXN ALL FCT KES
SBD ZEN EDO BNB NZD RDD XZC ENG ILS ITC
TMT BCN MIOTA RUB TZS BRL BSD DNA ZMW BAY
NAS SLS XLM MVR MWK NOK SEK STRAT MTL CLP
DASH HNL TAAS TRX JMD KRW MOP SAR VND ZEC
BNT DKK ETB OMR TTD XWC EGP KIN MLN NAD
PHP TNB ZAR CAD CHF MUR YER ARS BDT DENT
BMD CRC DGB GNF STEEM ETN MOON SC TRY AE
HUF JOD LBP LSK SRD BND CUP GAS UGX AMD
LSL BHD DJF DOGE GYD KWD POWR QAR

Note: The Currency request holds the key "Name" and its value is not case sensitive.

Usage

Currency.GetRate

GetCurrency provides current data of one certain currency. The data holds the currency code, country of origin, the description, the last currency value change in percentages, the exchange rate to USD and the time of the last update.

GetRateRequest defines the request message for the GetRate call. It needs the base currency and the destination currency. Supported currencies are here.

Base represents the base currency for the exchange rate.
Destination represents the destination currency for the exchange rate.

message GetRateRequest {
    string Base = 1;
    string Destination = 2;
}
{
    "Base":"EUR",
    "Destination":"USD"
}

GetRateResponse defines the response message for the GetRate call. It holds only the exchange rate of the request's base and destination.

Rate is the result exchange rate.

message GetRateResponse {
    float Rate = 1;
}
    "Rate":1.1655

Currency.GetCurrency

GetRate calculates the exchange rate between the base and the destination. The service takes the latest data from the source.

GetCurrencyRequest defines the request message for the GetCurrency and the SubscribeCurrency calls.

Name stands for the currency code for the currency. The Name value is not case sensitive.

message GetCurrencyRequest {
    string Name = 1;
{
    "Name":"CAD"
}

GetCurrencyResponse defines the response message for the GetCurrency call and the StreamingSubscribeResponse message.

Name stands for the currency code for the currency. Every Name value is capitalized.
Country holds the name of the country where the currency came from.
Description is the full name of the currency.
Change represents the latest currency change in the percentages.
RateUSD is the exchange rates between the currency and the USD. Both currency values are taken from the lastest source update.
UpdatedAt is the time of the last update of the currency in the source.

message GetCurrencyResponse {
   string Name = 1;
   string Country = 2;
   string Description = 3;
   float Change = 4;
   float RateUSD = 5;
   string UpdatedAt = 6;
}
{
    "Name": "CAD",
    "Country": "Canada",
    "Description": "Canadian Dollar",
    "Change": -0.02,
    "RateUSD": 1.3416,
    "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
}

Currency.SubscribeCurrency

SubscribeCurrency works as the GetCurrency call, except that it does not send a response instantly but wait until the database changes some of its value, then it sends all subscribed currency data to each client.

GetCurrencyRequest defines the request message for the GetCurrency and the SubscribeCurrency calls.

{"Name":"GBP"}
{"Name":"VND"}

StreamingSubscribeResponse defines the response message for the SubscribeCurrency call. It holds either GetCurrencyResponse or the Status error.

Get_currency_response defines the response message with the data about the currency.
Error defines the error status of the problem which occurred.

message StreamingSubscribeResponse {
    oneof message{
        GetCurrencyResponse GetCurrencyResponse = 1;
        google.rpc.Status Error = 2;
    }
}
{
    "GetCurrencyResponse": {
        "Name": "GBP",
        "Country": "England",
        "Description": "British Pound",
        "Change": -0.03,
        "RateUSD": 0.7815,
        "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
    }
}
{
    "GetCurrencyResponse": {
        "Name": "VND",
        "Country": "Vietnam",
        "Description": "Vietnamese Dong",
        "Change": 0.02,
        "RateUSD": 23185,
        "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
    }
}

Server logs:

[CURRENCY SERVICE]2020/07/25 10:25:14 [start] listening on 127.0.0.1:10502
[CURRENCY SERVICE]2020/07/25 10:25:23 [success] client successfully subscribed to: GBP
[CURRENCY SERVICE]2020/07/25 10:25:31 [success] client successfully subscribed to: VND
[CURRENCY SERVICE]2020/07/25 10:25:32 [update] currency data updated

Examples

For these examples, I am using the tool called gRPCurl to generate binary calls to gRPC servers.

GetRate

Currency.GetRate: {"Base":"RUB", "Destination":"USD"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Base":"RUB", "Destination":"USD"}' 127.0.0.1:10502 Currency.GetRate
{
    "Rate": 0.0139
}

Currency.GetRate: {"Base":"GBP", "Destination":"EUR"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Base":"GBP", "Destination":"EUR"}' 127.0.0.1:10502 Currency.GetRate
{
    "Rate": 1.0979
}

Currency.GetRate: {"Base":"CZK", "Destination":"CAD"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Base":"CZK", "Destination":"CAD"}' 127.0.0.1:10502 Currency.GetRate
{
    "Rate": 0.0596
}

Server logs

[CURRENCY SERVICE]2020/07/25 10:38:01 [start] listening on 127.0.0.1:10502
[CURRENCY SERVICE]2020/07/25 10:38:32 [handle] GetRate call, base: RUB, destination: USD
[CURRENCY SERVICE]2020/07/25 10:38:51 [handle] GetRate call, base: GBP, destination: EUR
[CURRENCY SERVICE]2020/07/25 10:39:11 [handle] GetRate call, base: CZK, destination: CAD

GetCurrency

Currency.GetCurrency: {"Name":"USD"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Name":"USD"}' 127.0.0.1:10502 Currency.GetCurrency
{
    "Name": "USD",
    "Country": "United States of America",
    "Description": "United States Dollar",
    "RateUSD": 1,
    "UpdatedAt": "2020-07-25 10:42:26.385028702 +0200 CEST m=+0.180421634"
}

Currency.GetCurrency: {"Name":"GBP"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Name":"GBP"}' 127.0.0.1:10502 Currency.GetCurrency
{
    "Name": "GBP",
    "Country": "England",
    "Description": "British Pound",
    "Change": -0.03,
    "RateUSD": 0.7815,
    "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
}

Currency.GetCurrency: {"Name":"CAD"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Name":"CAD"}' 127.0.0.1:10502 Currency.GetCurrency
{
    "Name": "CAD",
    "Country": "Canada",
    "Description": "Canadian Dollar",
    "Change": -0.02,
    "RateUSD": 1.3416,
    "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
}

Server logs

[CURRENCY SERVICE]2020/07/25 10:42:10 [start] listening on 127.0.0.1:10502
[CURRENCY SERVICE]2020/07/25 10:42:27 [handle] GetCurrency call: USD
[CURRENCY SERVICE]2020/07/25 10:42:32 [handle] GetCurrency call: GBP
[CURRENCY SERVICE]2020/07/25 10:42:38 [handle] GetCurrency call: CAD

SubscribeCurrency

Currency.SubscribeCurrency: {"Name":"CAD"}{"Name":"CZK"}{"Name":"GBP"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d @ 127.0.0.1:10502 Currency.SubscribeCurrency
{"Name":"CAD"}
{"Name":"CZK"}
{"Name":"GBP"}

UPDATE

{
    "GetCurrencyResponse": {
        "Name": "CAD",
        "Country": "Canada",
        "Description": "Canadian Dollar",
        "Change": -0.02,
        "RateUSD": 1.3416,
        "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
    }
}
{
    "GetCurrencyResponse": {
        "Name": "CZK",
        "Country": "Czech Republic",
        "Description": "Czech Koruna",
        "RateUSD": 22.526,
        "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
    }
}
{
    "GetCurrencyResponse": {
        "Name": "GBP",
        "Country": "England",
        "Description": "British Pound",
        "Change": -0.03,
        "RateUSD": 0.7815,
        "UpdatedAt": "2020-07-25 04:04:00 +0000 UTC"
    }
}

Server logs

[CURRENCY SERVICE]2020/07/25 10:46:01 [start] listening on 127.0.0.1:10502
[CURRENCY SERVICE]2020/07/25 10:46:03 [success] client successfully subscribed to: CAD
[CURRENCY SERVICE]2020/07/25 10:46:10 [success] client successfully subscribed to: CZK
[CURRENCY SERVICE]2020/07/25 10:46:15 [success] client successfully subscribed to: GBP
[CURRENCY SERVICE]2020/07/25 10:46:18 [update] currency data updated

Error handling

Currency.GetRate: {"Base":"USD", "Destination":"invalid"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Base":"USD", "Destination":"invalid"}' 127.0.0.1:10502 Currency.GetRate
ERROR:
    Code: NotFound
    Message: Currency was not found: call GetRate: destination currency 'INVALID' not found.

Currency.GetCurrency: {"Name":"invalid"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d '{"Name":"invalid"}' 127.0.0.1:10502 Currency.GetCurrency
ERROR:
    Code: NotFound
    Message: Currency "invalid" was not found.

Currency.SubscribeCurrency: {"Name":"invalid"}

[chutommy@localhost currencies]$ grpcurl --plaintext -d @ 127.0.0.1:10502 Currency.SubscribeCurrency
{"Name":"invalid"}
{
    "Error": {
        "code": 5,
        "message": "Currency \"INVALID\" was not found."
    }
}
{"Name":"USD"}
{
    "GetCurrencyResponse": {
        "Name": "USD",
        "Country": "United States of America",
        "Description": "United States Dollar",
        "RateUSD": 1,
        "UpdatedAt": "2020-07-25 11:02:50.145063563 +0200 CEST m=+45.314325138"
    }
}

Server logs

[CURRENCY SERVICE]2020/07/25 11:02:08 [start] listening on 127.0.0.1:10502
[CURRENCY SERVICE]2020/07/25 11:02:10 [error] handle error: call GetRate: destination currency 'INVALID' not found
[CURRENCY SERVICE]2020/07/25 11:02:18 [error] handle error: handling GetCurrency call: currency 'INVALID' not found
[CURRENCY SERVICE]2020/07/25 11:02:35 [error] currency "INVALID" not found
[CURRENCY SERVICE]2020/07/25 11:02:47 [success] client successfully subscribed to: USD
[CURRENCY SERVICE]2020/07/25 11:02:50 [update] currency data updated

Client

All clients can be built with the Protocol Buffer Compiler + gRPC plugin.

The protobuffer of the services: commodity.proto

Directory structure

_
├── config
│   ├── tests
│   │   ├── config_0.yaml
│   │   └── config_1.yaml
│   ├── config.go
│   └── config_test.go
├── data
│   ├── currencies.go
│   ├── currencies_test.go
│   ├── fetching.go
│   └── fetching_test.go
├── models
│   └── currency.go
├── protos
│   ├── currency
│   │   └── currency.pb.go
│   ├── google
│   │   └── rpc
│   │       └── status.proto
│   └── currency.proto
├── server
│   ├── currencies.go
│   ├── currencies_test.go
│   ├── handler.go
│   └── handler_test.go
├── config.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── main.go
├── Makefile
└── README.md

About

The Currencies is a microservice, which provides the latest exchange rates of all existing currencies using the gRPC calls

Topics

Resources

Stars

Watchers

Forks