2018年1月16日 星期二

[練習題] ASP.NET Core WebAPI - 台北市 YouBike 公開資料

這算是個練習的題目,原本覺得應該是個簡單的應用,沒想到實做下去遇到了幾個進階的操作,還蠻有趣的,用的是 ASP.NET Core WebAPI,但如果要用在 ASP.NET WebAPI 專案裡也是可以的,程式的部分並不會有多大的差異。寫程式的過程中還發想出不少的延伸應用情境,所以之後會有幾篇文章跟這篇的內容有所關連。

這篇文章會提到的內容:GZipStream, JsonConvert, AutoMapper



YouBike 臺北市公共自行車即時資訊

http://data.taipei/opendata/datalist/datasetMeta?oid=8ef1626a-892a-4218-8344-f7ac46e1aa48

image

資料存取網址

https://tcgbusfs.blob.core.windows.net/blobyoubike/YouBikeTP.gz

檔案格式為經 gz 壓縮之 json 檔,請下載後解壓縮使用

主要欄位說明

sno:站點代號、 sna:場站名稱(中文)、 tot:場站總停車格、 sbi:場站目前車輛數量、 sarea:場站區域(中文)、 mday:資料更新時間、 lat:緯度、 lng:經度、 ar:地(中文)、 sareaen:場站區域(英文)、 snaen:場站名稱(英文)、 aren:地址(英文)、 bemp:空位數量、 act:全站禁用狀態

回傳成功的 JSON 內容 ( 經過解壓縮後 )

image


上面就是要拿來應用的原始資料,第一個會遇到的狀況是,原始資料並不是直接給我們 JSON 資料,是經過 gzip 壓縮過的資料,所以要拿到實際可以用的資料就必須要在程式裡先做解壓縮處理。而第二個狀況就是 JSON 裡每個場站的資料雖然是結構化的,但 retVal 裡並不是直接給場站資料的 collection,而是 Key, Value 資料的  Collection,然後每個 key 都是對應場站資料的 sno (站點代號) 值。

以往拿到 JSON 資料後,會使用 Visual Studio 的「編輯 > 選擇性貼上 > 貼上 JSON 做為類別」的功能,快速產生對映 JSON 資料的類別。但如果是直接拿上面的原始 YouBike 資料去使用「貼上 JSON 做為類別」這個功能,那麼就會……

image

直接產生一堆以 Key 為名稱的類別,然後每個類別的屬性成員都一模一樣,因為每個 YouBike 場站資料所對映的類別應該是同一個才對,而不是每一個場站都有自己的類別,這部分會讓開發者感到稍微棘手,解決的方式有很多,不過我使用的是比較簡單的做法。


實作

建立 ASP.NET Core WebAPI 專案

image

image

專案請加入 JSON.NET 的 NuGet Package

image

建立 Infrastructure 資料夾,底下再新增 Models 與 Service 資料夾

Repository 資料夾則是會放取得 YouBike 資料的類別
Service 資料夾則是會放給 WebAPI Controller 取得 YouBike 資料的服務類別

image

Repository - 建立資料模型類別

image

YouBikeOriginalModel 類別

image

YouBikeStationModel 類別


Repository - 建立 YouBikeRepository 類別

IYouBikeRepository.cs

YouBikeRepository.cs


在 YouBikeRepository 的 RetriveData 方法裡,將原本被 gz 壓縮的內容使用 GZipStream 去解壓縮

image

在 RetriveData 方法最後所取得的是原始 YouBike 場站資料,還沒有對 retVal 做處理,retVal 型別為 JObject,這是為了要做接下來的 JSON 內容轉換而選擇的型別,

image

在 ReturnValue 屬性 ( JObject ) 裡,將 ChildrenTokens 展開後就可以看到各個的場站資料

image

最後在 GetStations 方法裡取得 JObject 的 PropertyValues,然後再逐一對取得的 Value 最反序列化為 YouBikeStationModel 處理,如此一來就可以取得全部的 YouBike 場站資料了

image

image


Service - 建立 Dto 類別

YouBikeStationDto.cs


Service - 建立 Service 類別

IYouBikeService.cs

YouBikeService.cs


專案加入 AutoMapper 的 Nuget packages

在 YouBikeService 的 GetStations 方法裡會使用到 AutoMapper 將 YouBikeStationModel 對映轉換為 YouBikeStationDto,所以專案要加入 AutoMapper 的相關 NuGet Packages

AutoMapper
AutoMapper.Extensions.Microsoft.DependencyInjection

image


Mapping - 新增 AutoMapper 對映轉換設定

Infrastructure 新增 Mapping 資料夾,然後增加 MappingProfile.cs 類別,

image

記得類別要繼承 AutoMapper 的 Profile,這樣專案啟動後 AutoMapper 才知道專案裡有多少的 Mapper 設定

image

MappingProfile.cs


修改 Startup.cs

修改 ConfigureServices 方法,加入 Dependency Injection 設定,包含 AutoMapper, YouBikeRepository, YouBikeService

image


修改 ValuesController.cs

類別新增型別為 IYouBikeService 的屬性,增加 ValuesController 的建構式並且增加注入 IYouBikeService 的處理,最後 Get 方法裡透過 YouBikeService.GetStations 方法所取得的 YouBike 場站資料輸出

image


輸出結果

image

image



看起來整個功能應該都做完了,不過還是有很多可以加強和修改的地方,例如每次取 API 資料都會再跟資料源頭取一次,但原始的 YouBike 資料是每分鐘更新一次,所以應該要把取得的原始資料做快取,存續時間為一分鐘,然後抓原始資料的處理應該是要放在背景並且使用排程方式處理,而不是由 WebAPI 的 Request 去驅動抓取原始資料。每個 YouBike 場站的資料(排除車輛的可租、可還、更新時間等會變動的內容)其實是應該個別儲存,爾後還可以做另外的延伸應用。

全台灣有使用 YouBike 系統的縣市區域有六個,但並非每個縣市區域都有把場站資料給公開出來讓大家使用,另外格式也不是都一樣,但還是有地方可以取得這些資料,有時間的話就另外再寫一篇文章來說明。


以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。