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:

  1. How to put the plugins for the console and web api ?
  2. How to cache the data  ? ( plugins / exchange rates)
  3. 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.

 

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/ )
NrPost 
1Start
2Reading NBR from internet
3Source control and build
4Badge and test
5CI and action
6Artifacts and dotnet try
7Docker with .NET Try
8ECB
9Intermezzo - Various implementations for programmers
10Intermezzo - similar code - options
11Plugin implementation
12GUI for console
13WebAPI
14Plugin in .NET Core 3
15Build and Versioning
16Add swagger
17Docker - first part
18Docker - second part
19Docker - build Azure
20Pipeline send to Docker Hub
21Play with Docker - online
22Run VSCode and Docker
23Deploy Azure
24VSCode see tests and powershell
25Code Coverage
26Database in Azure
27Sql In Memory or Azure
28Azure ConString, RSS
29Middleware for backward compatibility