.NET 6,微軟稱為“最快的.NET”,帶有了許多令人興奮的新功能、語言和效能改進。這是自 .NET Core 3.1 以來的第一個 LTS 版本,將支援三年。本次大版本釋出,增加了一個新特性:Minimal APIs,這是什麼技術?
.NET6 使編寫具有最小依賴性的 REST API 變得非常簡單。
Minimal APIs 似乎是微軟對 NodeJS(使用 ExpressJS)HTTP 伺服器的回應,它提供了最小的 API。但是微軟也對這項技術增加了幾個關鍵詞:
總結一句話:.NET 6 Minimal APIs 簡化了 HTTP Rest API 的設計和實現,讓開發者快速高效實現HTTP Rest API。
今天,我們花點時間,研究併科普一下.NET 6 Minimal APIs。
先看一下.NET 6 Minimal APIs的示例程式碼
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
在上面的示例中,app.MapGet 方法使用了內聯 lambda 表示式,完成一個 Controller Action 的業務邏輯,真的是超簡單。
超簡單完成一個 HTTP WebAPI 的定義:不再有 Startup.cs、API 控制器、額外依賴項等。
只需要這 4 行程式碼即可生成以下輸出:
探究一下這段程式碼背後的一些技術
上面的程式碼,微軟官方文件上,建議大家使用VS2022,其實用VS Code也可以
Tutorial: Create a minimal web API with ASP.NET Core
但是本機得先安裝.NET 6 SDK
安裝完成後,開啟VS Code,新建終端,建立一個Web Project
dotnet new web -o MyMinimalAPI
程式碼工程中,我們可以看到:
Program.cs這個類中沒有using了,當然也沒有main函式了,這裡跟大家解釋一下:
① .NET5 引入了Top-Level Class,可以沒有main函式,程式碼作為直接入口執行
② .NET 6 新增了一個很棒的新特性——“隱式全域性使用”
自動生成不可見的 using 語句並在全域性範圍內宣告它們,因此不必處理在每個檔案中重複宣告名稱空間的混亂。
我們開啟MyMinimalAPI.csproj 看看裡面的內容,有一個配置:
<ImplicitUsings>enable</ImplicitUsings>
dotnet build 後,找到 obj/Debug/net6.0 資料夾以檢視隱藏的自動生成檔案 - [ProjectName].GlobalUsings.g.cs。使用一個單獨的類來將所有 using 語句儲存在一個地方。
這個功能,讓我們不需要在每個檔案中重複宣告名稱空間的 using 引用了。的確很方便、簡單了。
當然,如果不想使用此功能,可以禁用 .csproj 檔案中的 ImplicitUsings 標誌。
在上面的示例中,app.MapGet 方法使用了內聯 lambda 表示式。同時還提供了:
app.MapPost()
app.MapPut()
app.MapDelete()
接下來,我們用一個簡單的示例,完成一個 demo。
完成一個 Minimal APIs 完整的 Demo
我們以一個簡單 Order 訂單為例,通過 Minimal APIs 實現 CRUD 設計和實現:
▌先準備好 Order 類和 IOrderService 介面以及 OrderServiceRepository
Order 類:
namespace NET6
{
public class Order
{
public int ID {get;set;}
public decimal Price {get;set;}
public string CustomAddress {get;set;}
public int State{get;set;}
}
}
IOrderService 介面:
namespace NET6
{
public interface IOrderService
{
Order GetOrder(int id);
void CreateOrder(Order order);
void DeleteOrder(int id);
void UpdateOrder(Order order);
}
}
OrderServiceRepository 類,使用記憶體集合模擬實現資料儲存層。
namespace NET6
{
public class OrderServiceRepository : IOrderService
{
static List<Order> orders = new List<Order>();
public Order GetOrder(int id)
{
return orders.FirstOrDefault(i=>i.ID == id)?? null;
}
public void CreateOrder(Order order)
{
orders.Add(order);
}
public void DeleteOrder(int id)
{
var order = orders.FirstOrDefault(i=>i.ID == id);
if(order!=null)
orders.Remove(order);
}
public void UpdateOrder(Order order)
{
DeleteOrder(order.ID);
CreateOrder(order);
}
}
}
▌在 Program.cs 類中,註冊 IOrderService 服務,新增 AddOrder 和 GetOrder Http Web API
using NET6;
var builder = WebApplication.CreateBuilder(args);
//registe IOrderService service
builder.Services.AddScoped<IOrderService, OrderServiceRepository>();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
//add order save API
app.MapPost("/add",(Order order,IOrderService service)=>
{
service.CreateOrder(order);
}).WithName("addorder");
//add order query API
app.MapGet("/getorder",(int id, IOrderService service)=>
{
return service.GetOrder(id);
}).WithName("getorder");
app.Run();
上面的低碼中,首先增加一個檔案級別的 namespace,這個地方為了和大家示意 Global Namespace 的區別
using NET6;
然後,在 ASP.NET DI 依賴注入框架中新增 IOrderService 服務:
//registe IOrderService service
builder.Services.AddScoped<IOrderService, OrderServiceRepository>();
新增訂單 Order 儲存API 服務:
//add order save API
app.MapPost("/add",(Order order,IOrderService service)=>
{
service.CreateOrder(order);
}).WithName("addorder");
上面這個 HttpWebAPI,我們採用了 Post 方式,請求是必須傳入 order 引數。
這個程式碼中,我們看到儲存訂單方法有2個引數,一個是 Order,另一個是 IOrderService,第二個引數,原生支援依賴注入,不需要顯式宣告建立。
類似的,繼續新增查詢訂單 API 服務
//add order query API
app.MapGet("/getorder",(int id, IOrderService service)=>
{
return service.GetOrder(id);
}).WithName("getorder");
▌執行除錯
在終端中輸入 dotnet run 指令,啟動執行除錯
dotnet run
除錯這3個 API,建議大家使用 PostMan 工具
先說一個小坑,一開始使用 PostMan 工具除錯儲存訂單介面,將 order 顯式地引數放到 Headers 中請求,結果一直不通:
看了微軟的示例文件後,建議直接將 order json 物件,http 請求體中以 raw 的方式發起請求
其他的 API 介面則沒有這個問題:
以上是.NET 6 Minimal APIs 的一些簡單介紹和實踐,希望能幫助大家。