Minimal API 是 .NET 6 提供的最新功能 , 對比傳統的 http://ASP.NET Core Web API 方式更加直接 , 你可以用幾行程式碼編寫好 REST API 。沒有了祖傳的 Startup.cs 和 Controller ,通過簡單的程式碼就可以完成 API 的開發。在第二階段的 .NET 挑戰賽中就以 .NET 6 中 的 Minimal API 作為學習的主線來完成相關的雲原生應用。有小夥伴問怎麼可以用好 Minimal API ,如何去架構一個 Minimal API 的雲原生解決方案 ,下面我和大家說說 。
再來認識一下 Minimal API
對比起傳統的 Web API , Minimal API 取消了 Controller , 檔案的組織方式更像 Node.js . 在以前要啟動一個 Web API , .NET 對比起 JavaScript , Go , Rust , Python 等語言的 Web 框架還是相對複雜的。.NET 團隊希望通過 Minimal API 簡化 .NET Web 框架 ,讓開發者能在一個檔案完成簡單 API 構建。以下是一個最基本的 Minimal API 專案。
MapGet 是 EndpointRouteBuilderExtensions 類的擴充套件方法, 你可以看到它設定了路由規則後, 會傳遞一個委託引數 , 編譯器會將它轉換為 RequestDelegate ,通過它來取代 Controller 的工作。然後使用 app.Run() 方法來執行我們的 Minimal API 應用程式。
架構 .NET 6 Minimal API 專案
在傳統的 Web API 通過 Controller ,針對不同的功能進行 CRUD 的開發, 但如果我們是 Minimal API 呢 , 要如何組織呢 ?還有我們是否還能用 Repository Pattern 呢 ?
- Controller 再見
假設我們要搭建一個關於課程資訊的 API, 有課程基本資訊(課程型別,課程列表)和選課資訊(學生選課,每門課學生選課資訊),如果從傳統 Web API 你需要新增 CourseController 和 BookController 兩個控制器,通過不同 Action 去對應相關路由 ,但對於 Minimal API 如果我們涉及很多的路由就會讓我們的 Program.cs 檔案過大,非常不好管理。那我們把功能點切分,或者說重新模擬 Controller 去劃分還是非常好的。
如上圖 ,是我畫的一個圖 ,通過把 Course 和 Book 劃分為兩個 Module , 在 Module 裡都包含了路由的設定 。這個時候我們做一個介面 ,因為每個 Module 都需要包含新增路由的方法,所以把它做成一個介面 IBaseModule ,以後不同的 Module 都可以用 。
如何新增進去 Program.cs ? 我們來用一個 IEndpointRouteBuilder 的擴充套件方法 ,把路由新增都歸類進來
public static class ModuleExtensions
{
public static void Routers(this IEndpointRouteBuilder builder)
{
CourseModule courseModule = new CourseModule();
BookModule bookModule = new BookModule();
courseModule.AddModuleRoutes(builder);
bookModule.AddModuleRoutes(builder);
}
}
這裡有一個技巧就是我們可以通過以下 typeof 找到繼承於 IBaseModule 的 Module 並將它例項化後呼叫新增路由的方法。
public static void Routers(this IEndpointRouteBuilder builder)
{
var modules = typeof(IBaseModule).Assembly
.GetTypes()
.Where(p => p.IsClass && p.IsAssignableTo(typeof(IBaseModule)))
.Select(Activator.CreateInstance)
.Cast<IBaseModule>();
foreach(var module in modules)
{
module.AddModuleRoutes(builder);
}
}
- Repostitory 模式能延續嗎 ?
這是毫無疑問可以繼續使用。通過 Repository 模式你不需要去關心你所使用的 ORM 是什麼 , 與 ORM 的所有處理過程都在 Repository 層中處理掉 , 通過這樣去減少耦合, 提供更好的可測試性。在微軟文件中,有以下的比較
在 Minimal API 使用 Repository Pattern 在整體上和傳統的 http://ASP.NET MVC 沒有不同 ,這裡是我用 Repository 模式架構的 Minimal API 的截圖
注意一點有人認為 Repository 模式有點過時 ,和過度架構 , 但我覺得還是非常有必要的,因為這樣可以更好管理你的專案。
- 依賴注入
依賴注入解決了應用程式如何獨立於物件建立方式的問題。當您需要可配置的應用程式單元測試時,這非常有用。隨著應用程式的規模和複雜性的增長,依賴注入可幫助您更輕鬆地更改應用程式。在 http://ASP.NET Core 中有非常好用的依賴注入方式 , 這點在 Minimal API 也是。由於我們針對功能模組去管理 ,所以在依賴注入時也可以針對模組功能去進行 。以下是我針對模組依賴注入的設計, 結合 Repository 模式以及上面提到的 ModuleExtension.cs 進行的調整 , 我也把關於資料連線公用的依賴注入也抽象了出來。
public static class ModuleExtensions
{
static readonly List<IBaseModule> moduleList = new List<IBaseModule>();
private static IEnumerable<IBaseModule> GetModules()
{
var modules = typeof(IBaseModule).Assembly
.GetTypes()
.Where(p => p.IsClass && p.IsAssignableTo(typeof(IBaseModule)))
.Select(Activator.CreateInstance)
.Cast<IBaseModule>();
return modules;
}
public static void Routers(this IEndpointRouteBuilder builder)
{
foreach(var module in moduleList)
{
module.AddModuleRoutes(builder);
}
}
public static void AddIoC(this IServiceCollection services)
{
foreach(var module in GetModules())
{
module.AddModuleIoC(services);
moduleList.Add(module);
}
}
public static void AddGlobalConfig(this IServiceCollection services)
{
services.AddScoped<CourseDataContext>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
}
}
注意一些地方 , 雖然在 Minimal API 上 ,我們的依賴注入雖然把不同的Services 註冊了單例給 RequestDelegate 所呼叫 , 但在作為引數傳送時,要新增 [FromServices] 屬性標籤才有效 , 如下
app.MapGet("/Course/GetCourse" ,([FromServices] ICourseService courseService , int typeID)=> {
return courseService.GetCourseList(typeID);
});
Minimal API or Web API
在 http://ASP.NET Core 中開發 API 時,你 90% 都在使用 http://ASP.NET Core MVC。而當你使用 http://ASP.NET Core MVC 架構 Web API 時 , 你會發現有點複雜 , 你需要符合 http://ASP.NET Core MVC 的所有要求 。而 Minimal API 正好解決了這些問題 , 特別對於一些只做 API 或者 入門的開發者, 只需要簡潔的程式碼就能完成類似 Node.js 一樣的工作 。有人問我 Minimal API 會取代傳統的 Web API 嗎 ?我可以告訴大家不會。還是那句話 , 選擇符合專案需求的方法才是正道的。
小 結
在雲原生的年代 , Minimal API 是 .NET 的又一把利器 。.NET 6 的 Minimal API 要用好 ,實際上還是用到不少舊知識,像 Module 的構建方式,我參考了開源的 Carter , 像 Repository 模式還是沒有變 ,當然還是那些熟悉的語法 C# , 這就是我們常說的 ”萬變不離其中“ 。Minimal API 不是要取代 Web API , 更多是給開發人員多一個選擇 。作為 .NET 學習挑戰賽知識點的補充 , 希望能給各位小夥伴更深刻了解 Minimal API 在實際應用場景的技巧 。本次的示例程式碼也放到我的 GitHub 上了 ,如果各位小夥伴感興趣可以訪問該連結獲取完整的程式碼。
相關資源
- 學習 Minimal API , 請訪問該連結
https://docs.microsoft.com/zh... - 學習 Repository 模式 , 請訪問該連結
https://docs.microsoft.com/zh...
長按識別二維碼
關注微軟中國MSDN