Kamarád Michal Bláha se na Facebooku sháněl po API, které by mu dalo k dispozici kurzy měn včetně historie. Vzpomněl jsem si, že jsem něco takového napsal, tak jsem to oprášil, přeleštil a dávám k dispozici nejenom jemu, ale i všem ostatním zájemcům..
Aplikace využívá API České národní banky. Ta publikuje v jednoduchém textovém formátu (v podstatě CSV, jenom se pro oddělení používá svislítko) aktuální i historické kurzy. Nevím jak daleko do minulosti, ale minimálně do roku 2000.
Napsal jsem tedy třídu, která tato data stáhne, proparsuje a publikuje:
Z programátorského hlediska je to kód dost přímočarý a jednoduchý. Pozoruhodných je pouze pár drobností:
- Všechny čtyři třídy jsem vložil do jednoho souboru i s ukázkovou konzolovou aplikací. Což není obecně pro praxi příliš dobré řešení, ale pro ukázkový kód ideální. Vzhledem k jednoduchosti předpokládám, že si prostě třídy
CnbClient
,CnbExchangeRateList
aCnbExchangeRate
nakopírujete někam do svého projektu. Nedělal jsem z toho ani samostatné DLL s NuGet balíčkem, jak je to jednoduché. - Obecně není dobrý nápad psát si vlastní parsování CSV, pokud dopředu neznáme přesný formát dat, může tam být quotování atp. Obvykle používám pro import a export knihovnu CsvHelper. Zde je ale formát natolik pevný, že jsem dal přednost jednoduchosti.
- Výsledek je předáván jako třída
CnbExchangeRateList
, což je potomekReadOnlyCollection
. Původně jsem chtěl vracet jenomIEnumerable<CnbExchangeRate>
, ale pak jsem si uvědomil, že bych měl někde předávat i datum, k němuž byl vydán kurzovní lístek. Ten je obecně vydáván jenom v pracovních dnech a pokud se zeptáte na nepracovní den, vrátí API poslední platný. Datum, k němuž byl lístek vydán, je dostupný jako vlastnostDate
. - Klient je jednoduše napsaný jako asynchronní (metoda
GetRatesAsync
). Pro použití v synchronním prostředí jsem přidal wrapperGetRates
, který se zeptá přímo na vlastnostResult
. - V testovací aplikaci lze vidět poměrně pokročilé využití string interpolation včetně zarovnávání a formátovacích řetězců, aby to vyrobilo hezkou tabulku.
- V přechodném období ČNB publikovala kromě kurzu EUR i přepočítané kurzy tehdejších národních měn. Ty moje třída ignoruje (zastaví zpracování na prvním prázdném řádku).
- Ošetření chyb není příliš robustní, resp. kód na první chybě zhavaruje a nepokouší se ji nějak řešit (např. pokračovat zpracováním dalšího řádku). To je záměr. U aplikace tohoto typu mohou nastat v zásadě pouze dva druhy chyb: buďto se nepodařilo data načíst vůbec (server ČNB je nedostupný atd.) nebo se je nepodařilo správně proparsovat. Ve druhém případě se nejspíše změnil formát, v němž jsou publikována a v takovém případě je lepší rovnou zhavarovat, než se z toho pokoušet nějak vylhat, protože by mohlo dojít k chybné interpretaci dat.