Creating the WebAPI–part 13
I am now tired of continuously improving the console application – so now some work that others can see really. Creating the WebAPI is simple as a project – and I was amazed to see a WeatherForecast controller.
I need just to be able to see the today exchange rates via API . So created a TodayRates , modify the launchSettings.json in order to start with my controller.
I need the plugin that loads to be a global dependency. So I add as a Singletion in the services
services.AddSingleton< LoadExchangeProviders>(new LoadExchangeProviders(“plugins”));
and then I inject into the controller constructor ( I can do in the method also, but many methods needs the same dependency )
public TodayRates(ILogger<TodayRates> logger, LoadExchangeProviders prov)
{
_logger = logger;
_prov = prov;
}
Now I need a method to see what are the banks / plugins that are loaded . Linq to the rescue :
[HttpGet]
public IEnumerable<string> Banks()
{
return _prov
.LoadExchange()
.Select(it=>it.Bank)
.ToArray();
}
Now we should load the data from the provider to show actual rates
public async IAsyncEnumerable<ExchangeRates> Rates(string bank)
{
var provBank = _prov
.LoadExchange()
.FirstOrDefault(it => string.Equals(bank, it.Bank, StringComparison.InvariantCultureIgnoreCase));switch (provBank)
{
case null:
yield return null;
break;
default:
{
await foreach (var data in provBank.GetActualRates())
{
yield return data;
}break;
}
}}
All good. There are 3 problems:
- How to put the plugins for the console and web api ?
- How to cache the data ? ( plugins / exchange rates)
- Should we throw an exception when a bank does not exists, instead of returning null ?
Thinking of this code, I realized that I begin to put logic into controllers. So – let’s move from the controller to the business.
For example, now I have this:
[HttpGet]
public IEnumerable<string> Banks()
{
return _prov.Banks();
}
And this
[HttpGet]
public IAsyncEnumerable<ExchangeRates> Rates(string bank)
{
return _prov.Rates(bank);
}
So now I can change in the Business Layer without problems.
Looking at the Console Application vs WebAPI, I realized that are different. The console is loading the whole data from the providers – the WebAPI is loading on demand. We could do for the console the same behavior – but the console is loading very fast all data.
For the answer at
Should we throw an exception when a bank does not exists, instead of returning null ?
– seems to be yes.
So instead of
case null:
yield return null;
I put
case null:
throw new ArgumentOutOfRangeException(nameof(bank),$”cannot find {bank}”);
For the 2 questions, the answer next time.
Infovalutar
And one hour passes...(This is the result of 1 hour per day auto-challenge as a full cycle developer for an exchange rates application)
( You can see the sources at https://github.com/ignatandrei/InfoValutar/ )
Leave a Reply