在树莓派上使用 PowerShell 调用 Azure 上的 .NET Core API 获取疫情数据
點(diǎn)擊上方藍(lán)字關(guān)注“汪宇杰博客”
導(dǎo)語
最近因?yàn)橐咔楸魂P(guān)在家里,做了個(gè)無聊成就:我們將在樹莓派上用 PowerShell 調(diào)用 Azure 上的一個(gè) .NET Core 寫的 API 來獲取疫情數(shù)據(jù)。
疫情數(shù)據(jù)API
疫情數(shù)據(jù)來源于騰訊新聞的一個(gè)實(shí)時(shí)更新的頁(yè)面,原始 API 地址為:
https://view.inews.qq.com/g2/getOnsInfo?name=wuwei_ww_cn_day_counts"
然而我們沒有辦法直接使用,因?yàn)樗姆祷鼐尤徊皇且?guī)范的 JSON:
因此,我只能自己 996 一下,用 .NET Core 包裝了騰訊的 API,做了規(guī)范化的輸出,最終結(jié)果為:
我們只需要將騰訊 API 中的 data 字符串取出,反序列化為強(qiáng)類型 model 即可。
public class InfectionData
{
? ? public DateTime Date { get; set; }
? ? public int Confirm { get; set; }
? ? public int Suspect { get; set; }
? ? public int Dead { get; set; }
? ? public int Heal { get; set; }
}
由于 System.Text.Json 福報(bào)非常多,我依舊使用老牌 Json.NET 搞定數(shù)據(jù)轉(zhuǎn)換:
var data = await _httpClient.GetStringAsync(_settings.Value.DataSource);
var apiRes = JsonConvert.DeserializeObject<CoronavirusApiResponse>(data);
var infectionData = JsonConvert.DeserializeObject<IEnumerable<InfectionData>>(apiRes.Data);
代碼地址:https://github.com/EdiWang/DotNet-Samples/tree/master/CoronavirusReport
其中用到的知識(shí)點(diǎn)為 HttpClient + Polly,這是 .NET Core 調(diào)用 REST API 最安全可靠的實(shí)踐。
簡(jiǎn)單來說,就是為了調(diào)一個(gè)API,你得針對(duì)這個(gè)API建一個(gè)接口、一個(gè)實(shí)現(xiàn),把 HttpClient 類型通過 services.AddHttpClient 加入 DI 傳進(jìn)來使用,最后利用 Polly 配置出錯(cuò)自動(dòng)重試等異常處理。
public interface ICoronavirusApiClient
{
? ? Task<IEnumerable<InfectionData>> GetInfectionDataAsync();
}
public class CoronavirusApiClient : ICoronavirusApiClient
{
? ? private readonly HttpClient _httpClient;
? ? private readonly ILogger<CoronavirusApiClient> _logger;
? ? private readonly IOptions<AppSettings> _settings;
? ? public CoronavirusApiClient(
? ? ? ? HttpClient httpClient,?
? ? ? ? ILogger<CoronavirusApiClient> logger,?
? ? ? ? IOptions<AppSettings> settings)
? ? {
? ? ? ? _logger = logger;
? ? ? ? _settings = settings;
? ? ? ? _httpClient = httpClient;
? ? }
? ? public async Task<IEnumerable<InfectionData>> GetInfectionDataAsync()
? ? {
? ? ? ? var data = await _httpClient.GetStringAsync(_settings.Value.DataSource);
? ? ? ? var apiRes = JsonConvert.DeserializeObject<CoronavirusApiResponse>(data);
? ? ? ? var infectionData = JsonConvert.DeserializeObject<IEnumerable<InfectionData>>(apiRes.Data);
? ? ? ? var infectionDataArray = infectionData as InfectionData[] ?? infectionData.ToArray();
? ? ? ? _logger.LogInformation($"Got {infectionDataArray.Length} records from '{_settings.Value.DataSource}'");
? ? ? ? return infectionDataArray;
? ? }
}
services.AddHttpClient<ICoronavirusApiClient, CoronavirusApiClient>()
? ? ? ? .AddTransientHttpErrorPolicy(builder =>
? ? ? ? builder.WaitAndRetryAsync(3, retryCount =>
? ? ? ? ? ? ? ? TimeSpan.FromSeconds(Math.Pow(2, retryCount)),
? ? ? ? ? ? (result, span, retryCount, context) =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? _logger?.LogWarning($"Request failed with {result.Result.StatusCode}. Waiting {span} before next retry. Retry attempt {retryCount}/3.");
? ? ? ? ? ? }));
至于為什么不能簡(jiǎn)單粗暴 new 一個(gè) HttpClient 直接調(diào)API,推薦觀看另一名 MVP Steve Gordon 的視頻《Let's Talk HTTP in .NET Core》:https://www.youtube.com/watch?v=ojDxK_-I-To ??(咦,這是什么不存在的網(wǎng)站)
最后,我把處理好格式的的疫情 API 部署到了Azure國(guó)際版的 App Service 上。
https://covid19cn.azurewebsites.net/infectiondata
Linux居然有PowerShell?
由于 Windows 10 早已是一盤咖喱拌飯,導(dǎo)致在樹莓派上最好用的系統(tǒng)只能是 Linux,而我這種微軟系程序員顯然不熟悉 bash,如果能用上 PowerShell 那就太好了!隨著微軟的開源、開放(Linux First, Windows Last)的態(tài)度,PowerShell 其實(shí)也和 .NET 一樣,已經(jīng)能夠跨平臺(tái)運(yùn)行。
以樹莓派官方系統(tǒng) Raspbian 為例,安裝 PowerShell 的方式如下:
sudo apt-get install libunwind8
wget?https://github.com/PowerShell/PowerShell/releases/download/v7.0.0-rc.3/powershell-7.0.0-rc.3-linux-arm32.tar.gz
mkdir ~/powershell
tar -xvf ./powershell-7.0.0-rc.3-linux-arm32.tar.gz -C ~/powershell
sudo ln -s ~/powershell/pwsh /usr/bin/pwsh
sudo ln -s ~/powershell/pwsh /usr/local/bin/powershell
powershell
PowerShell 的最新發(fā)布可以關(guān)注官方 GitHub:https://github.com/PowerShell/PowerShell/releases
參考:https://www.hanselman.com/blog/InstallingPowerShellCoreOnARaspberryPiPoweredByNETCore.aspx
另外,如果你和我一樣用樹莓派4,那么 Ubuntu 19.10.1 作為64位系統(tǒng),可以通過相同方法安裝64位 PowerShell,感興趣的可以嘗試。
現(xiàn)在我們可以愉快的調(diào)用疫情數(shù)據(jù)了!PowerShell 自帶一個(gè)?Invoke-RestMethod 方法專門用來調(diào)用 REST API,非常方便,996。而?Format-Table 則可以把返回的 JSON 對(duì)象直接用表格形式來展示,更不會(huì) 996!
Invoke-RestMethod 參考:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7
當(dāng)然,你在 Windows?咖喱味 PC 上也能用經(jīng)典 PowerShell 做這件事:
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的在树莓派上使用 PowerShell 调用 Azure 上的 .NET Core API 获取疫情数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .Net Core中IOC容器的使用
- 下一篇: .NET Core开发实战(第7课:用A