以前寫過ASP.NET Core 2.x的REST API文章,今年再更新一下到3.0版本。 先決條件 我在B站有一個非常入門的ASP.NET Core 3.0的視頻教程,如果您對ASP.NET Core不瞭解,就可以先看一下裡面的基礎知識和API相關的內容,地址是:https://www.bili ...
以前寫過ASP.NET Core 2.x的REST API文章,今年再更新一下到3.0版本。
先決條件
我在B站有一個非常入門的ASP.NET Core 3.0的視頻教程,如果您對ASP.NET Core不瞭解,就可以先看一下裡面的基礎知識和API相關的內容,地址是:https://www.bilibili.com/video/av65313713/。
預備知識:ASP.NET Core 和 C#
工具:Visual Studio 2019最新版(VSCode、VS for Mac,Rider等也湊合),POSTMAN
Web API
Web API通常是指“使用HTTP協議並通過網路調用的API”,由於它使用了HTTP協議,所以需要通過URI信息來指定端點。
API是Application Programming Interface的縮寫,是軟體的外部介面。也就是說,針對某個軟體,人們可以知道它的外部功能,但並不知道(也不需要知道)它的內部運作細節,為了從外部調用某些功能,需要指定軟體的調用規範等信息,這樣的規範就是API。
所以Web API就是一個Web系統,通過訪問URI可以與其進行信息交互。
大多數的 Web API 並不是 RESTful API
REST一詞是在2000年首次出現的,它是由Roy Fielding博士在《架構風格以及基於網路的軟體架構設計》這篇論文中提到的。他為REST風格的API制定了一套約束規範或者叫架構風格。
所以準確的說,只有符合了Roy Fielding架構風格的Web API才能稱作是RESTful API。但是在實際開發中,有時候也有不完全符合Roy Fielding架構風格的情形出現,針對這點我將會在稍後的文章中介紹。
MVC模式與RESTful API
本系列文章中我將使用ASP.NET Core 3.0 MVC 來構建 RESTful API。
MVC(Model-View-Controller)我認為是一種主要用來構建UI的架構模式。對於MVC模式其實有很多種解釋存在,但是無論那種解釋,它們都會強調松耦合和關註點分離(separation of concerns)。
也是由於這兩點的存在,程式的可測試性會大大提高,程式各部分的可復用性也很高。
更多關於MVC的介紹,可以看一下微軟的官方文檔:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/overview?view=aspnetcore-3.0
註意:MVC不是一個完整的應用程式架構,我認為它主要是用在展示層。所以實現UI就是MVC的一部分工作。
如何把MVC映射到API
我認為API同樣可以看作是UI,它就是為API消費者所提供的UI。
讓我們把MVC的三部分分別對應到API:
-
Model,它負責處理程式數據的邏輯。這裡的Model可以包含在當前級別獲取從存儲獲取數據的邏輯。但是有一些Model不包含任何邏輯,例如API所使用的DTO(Data transfer objects),這類的Model會被串列化到響應的body裡面。
-
View,它是程式里負責展示數據的那部分。在構建API的時候,View就是數據或資源的展示。現在通常使用JSON格式。
-
Controller,它負責View和Model之間的交互。包括處理用戶輸入,用API的術語來講,和API交互的“用戶”就是指API的消費者,這類用戶通常是另一個程式,例如Angular的SPA程式。
下麵看看MVC這三部分的依賴關係:
Controller和View依賴於Model,Controller依賴於View,這也是分離的一個好處。
換句話說,Controller會選取適當的View來展現給用戶,並一同把用戶請求的Model數據帶回去。
當API消費者發出請求的時候,在Controller上面的Action將會被觸發,Controller會把接收到的輸入數據發送給負責業務處理邏輯或數據訪問邏輯的那部分程式。然後Controller會把Model返回給View,這裡的View就是資源的展示(通常是JSON格式)。
接下來我們就是用這套概念和ASP.NET Core 3.0 來創建RESTful API。
但是請註意,通過ASP.NET Core MVC或API模板建立出來的新項目,我們並不會直接得到RESTful(REST架構風格)的API。我們必須在這個基礎上,自己構建RESTful的API,因為之前已經提到了,標準的RESTful API有很多約束和規範。
創建ASP.NET Core 3.0 Web API項目
打開VS2019,選擇項目模板ASP.NET Core Web Application:
然後為項目和解決方案起名字,並選擇所在目錄:
然後選擇ASP.NET Core的項目模板:
首先要選擇ASP.NET Core 3.0。
這裡我選擇了API這個模板。在以前,我通常會選擇Empty模板,因為其它模板通常包含很多我不需要的東西,但是ASP.NET Core 3.0的API模板還是比較乾凈的,可以接受。
最後,由於本課程中不需要使用HTTPS和Docker,所以把這兩個東西都勾掉。
解剖 ASP.NET Core 3.0 API 模板項目
點擊Create,項目就建立好了:
先看看 appsettings.json:
裡面只有預設的Log配置以及允許的Hosts。
而appsettings.Development.json裡面:
也只有關於Log的預設配置。
註意:您需要知道appsettings.json 和 appsettings.Development.json之間的關係,關於這點可以看我ASP.NET Core 3.0的入門視頻教程,但是更簡單的辦法是看一下官方文檔:在ASP.NET Core中使用多個環境。
項目模板里還有兩個類我們不需要,所以把它刪掉,分別是WeatherForecastController和WeatherForecast:
Program.cs:
這裡其實就是整個程式的入口,Main方法負責配置和運行整個Web程式。
由於這是一個Web項目,所以我們還需要一個宿主(Host),這個宿主就是由下麵的CreateHostBuilder方法來負責創建的。該方法首先會創建出一個實現了IHostBuilder介面的類(HostBuilder)的實例,然後調用它的Build方法來創建宿主(類型為Host,實現了IHost介面),最後調用宿主上面的Run方法來運行程式。
我們暫時不修改這裡面的代碼,所以一切都會按照項目模板預設的配置進行,註意到下麵的方法里我們使用到了Startup這個類:
所以我們來看看Startup類。
Startup.cs
在這個類的構造函數里:
我們看到IConfiguration被註入了,這樣就允許我們使用配置信息了,例如appsettings.json裡面的配置信息。
下麵有一個ConfigureServices方法:
這個方法負責向服務容器裡面註冊服務,已註冊的服務可以通過依賴註入的方式在整個應用程式的其它地方進行使用。這裡的服務是一個比較廣義的概念,它就是一個在整個程式中做一些通用性操作的組件。
這裡面只有一句話:
在3.0之前的版本里,這裡面應該寫的是services.AddMvc();,實際上在ASP.NET Core 3.0裡面這樣寫也是可以的。但是AddMvc()裡面不僅僅包含用於構建API的服務,還包含很多其它服務,例如構建View視圖和TagHelper相關的服務等。而AddControllers()方法只包含用於構建API的那些服務,例如Controller的支持、Model綁定、Data Annotation和格式化器等等。
最下麵還有一個Configure方法:
這個方法使用到了在ConfigureServices方法裡面註冊和配置的服務,所以這個方法是在ConfigureServices方法之後被調用的。
Configure方法是用來指定ASP.NET Core Web程式是如何響應每一個HTTP請求的。換句話說,也就是我們在這裡配置請求的管道,配置的方法就是在這裡添加很多中間件(Configure方法裡面每一個app.UseXxx就是添加一個中間件,可以查看中間件的官方文檔來瞭解更多)。
在開發環境的時候,如果有異常發生,那麼會展示出一個異常頁面:
app.UseAuthorization(),它會為整個Web程式添加授權的能力。當你需要考慮API安全性的時候,這點就很重要了。通常授權配置是在ConfigureServices方法里完成的,而我現在沒有對授權進行配置,但是app.UseAuthorization()仍然會允許API可以被匿名的訪問。
其它這幾句話:
這幾句話都是用來指定如何把HTTP請求分配到特定的Controller Action上面的。也就是說這是關於路由的。
很重要的一點就是:每一個請求會按照代碼的順序穿越所有在這裡添加的中間件。但是每一個中間件都有可能將請求短路,這樣的話請求就不會進入下一個中間件了,而會按照原路返回。
所以,添加中間件的順序非常重要。如果你把授權中間件放在了Controller的後邊,那麼即使需要授權,那麼請求也會先到達Controller並執行裡面的代碼,這樣的話授權就沒有意義了。
修改項目啟動配置
我喜歡使用控制台啟動Web程式,這樣可以很直觀的看到Log信息。為達到這個目的,可以修改launchSettings.json文件:
修改後,在項目的Debug屬性里也有體現:
由於我主要是使用POSTMAN來調用API,所以我不需要Launch Browser(啟動瀏覽器)。
運行程式
可以看到程式可以正常運行,並且在控制臺上有日誌的輸出。
添加數據存儲功能
想要做RESTful API的話,我們還需要數據,這裡我準備採用SQLite來作為數據存儲,使用Entity Framework Core 作為 ORM來與資料庫進行交互。針對Entity Framework Core 3.0 如何在ASP.NET Core 裡面使用,官方有個很不錯的教程。
下麵開始在項目里添加SQLite和EFCore 3.0(這部分官方文檔可以點擊這裡)的支持:
-
首先,需要在我們的項目里通過Nuget添加 Microsoft.EntityFrameworkCore.Sqlite 這個包。
-
然後,還需要安裝 Microsoft.EntityFrameworkCore.Tools 這個包,它是用來做遷移的,關於這個包的更多功能解釋,可以查看官方文檔。
建立Entities
我們先把項目的需求想的簡單一點,暫時我們就做一個公司和公司員工的維護,兩個Entity,兩個表。
公司(Company)的Entity:
為什麼使用Guid作為主鍵的類型?
員工(Employee)的Entity