目錄:
先決條件:介紹本文旨在全面概述程序員在創建 API 時應遵循的最佳實踐。無論是使用 .NET 6 Web API 還是任何其他框架,這些做法對于提供設計良好且可靠的 API 都是必不可少的。
對 API 進行版本控制
什么是 API 版本控制?
API 是軟件。軟件的每個部分都需要在某個時候進行更新。在 API 上創建一些更新時,需要確保這些更改不會影響 API 使用者(用戶)。為確保這一點,您需要引入 API 版本控制。
為什么需要 API 版本控制?
如果您的目標是開發強大且可擴展的 Web 應用程序,請考慮從 Toptal 聘請 ASP.NET 開發人員。憑借他們在創建高性能解決方案方面的深厚專業知識,Toptal 的 ASP.NET 專業人員有能力提供滿足復雜業務需求的尖端應用程序,確保頂級公司和初創公司有效地實現其技術目標。
向后兼容性:它確保客戶端可以繼續使用舊版本,而新客戶端可以利用更新的功能。
API 演進:隨著 API 的演進,版本控制允許您引入新功能、棄用過時的功能并進行改進,而不會中斷現有客戶端。
客戶端靈活性:不同的客戶端可能有不同的要求,或者可能需要特定版本的 API 中提供的特定功能。
ASP.NET Web API 版本控制
GET /products HTTP/1.1
Host: api.example.com
Accept: application/json
X-API-Version: 2
Microsoft.AspNetCore.Mvc.Versioning
//Program.cs C# class:
builder.Services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
});
在 ProductsController 中,使用 MapToApiVersion 屬性修飾操作方法,以指定每個方法的版本。
[ApiController]
[Route("v{version:apiVersion}/products")]
public class ProductsController : ControllerBase
{
// GET v1/products
[HttpGet]
[MapToApiVersion("1.0")]
public IActionResult GetV1()
{
// Implementation for version 1
}
// GET v2/products
[HttpGet]
[MapToApiVersion("2.0")]
public IActionResult GetV2()
{
// Implementation for version 2
}
}
相信我,遵循這些提示將使您在 .NET 6 中的 API 開發變得輕而易舉!:D
使用正確的 HTTP 方法
什么是 HTTP 方法?
最常用的方法是:
GET:檢索資源的表示形式。POST:創建新資源。
PUT:更新現有資源或創建新資源(如果不存在)。
PATCH:部分更新現有資源。
DELETE:刪除資源。
使用正確的 HTTP 方法很重要,因為它可以確保遵守 REST 架構風格的原則,改進 API 設計和可維護性,通過實施適當的訪問控制來增強安全性,促進可伸縮性和緩存機制,并實現與 Web 上各種客戶端和服務器的互操作性和兼容性。
RESTful 原則:正確使用 HTTP 方法符合具象狀態傳輸 (REST) 的原則。RESTful API 利用這些方法的語義為客戶端創建統一且可預測的接口。
**語義清晰:**每個 HTTP 方法都具有特定的含義,使您的 API 端點更加直觀和不言自明。開發人員可以根據所使用的 HTTP 方法輕松了解端點的用途和功能。
何時使用每種 HTTP 方法?
GET:使用 GET 從資源中檢索數據。它應該不會對服務器產生任何副作用。POST:使用 POST 創建新資源。請求有效負載通常包含新資源的數據,服務器為其分配唯一標識符。
PUT:使用 PUT 更新現有資源或創建新資源(如果不存在)。請求負載包含要更新的資源的完整表示形式。
PATCH:使用 PATCH 對現有資源執行部分更新。請求有效負載僅包括需要應用于資源的更改。
DELETE:使用 DELETE 刪除由其唯一標識符標識的資源。
故事時間:
好像這還不夠,當我無意中設置“PUT”方法而不是“DELETE”來刪除資源時,我遇到了另一個錯誤,導致數據持久且頑固。
.NET 6 示例
[ApiController]
[Route("products")]
public class ProductsController : ControllerBase
{
// GET /products
[HttpGet]
public IActionResult Get()
{
// Implementation to retrieve all products
}
// GET /products/{id}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
// Implementation to retrieve a specific product by ID
}
// POST /products
[HttpPost]
public IActionResult Create(ProductDto product)
{
// Implementation to create a new product using the provided data
}
// PUT /products/{id}
[HttpPut("{id}")]
public IActionResult Update(int id, ProductDto product)
{
// Implementation to update an existing product identified by the ID
}
// PATCH /products/{id}
[HttpPatch("{id}")]
public IActionResult PartialUpdate(int id, JsonPatchDocument<ProductDto> patchDocument)
{
// Implementation to apply partial updates to an existing product
}
// DELETE /products/{id}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
// Implementation to delete a specific product by ID
}
}
保護 API
開發 .NET 6 Web API 時,API 安全性需要考慮幾個重要方面:
認證:
.NET 6 中的 JWT 持有者令牌示例
// Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "your_issuer",
ValidAudience = "your_audience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_security_key"))
};
});
}
授權
// ProductsController.cs
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
[HttpGet]
[Authorize(Roles = "admin")]
public IActionResult GetProducts()
{
// Implementation for retrieving products
}
[HttpPost]
[Authorize]
public IActionResult CreateProduct(ProductDto product)
{
// Implementation for creating a new product
}
}
速率限制
在 .NET 6 中,可以使用 AspNetCoreRateLimit 庫實現此目的。
services.AddMemoryCache();
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
app.UseIpRateLimiting();
{
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Forwarded-For",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
}
]
}
}
緩存響應
什么是響應緩存?
為什么要使用響應緩存?
我將根據我的經驗向您解釋 3 個最有力的原潁�
改進的性能:無需重復執行相同的昂貴計算或數據庫查詢,而是從內存或緩存存儲中快速提供緩存響應。緩存響應可縮短響應時間并提高 API 的整體性能。節省帶寬:后續請求可以獲取緩存的響應,從而節省帶寬,而不是每次都傳輸整個響應。緩存響應可減少通過網絡發送的數據量。
減少服務器負載:通過提供緩存響應,服務器處理的請求更少,從而減少服務器負載并提高可伸縮性。這在處理高流量或資源密集型 API 時尤其有用。
.NET 實現
添加依賴項:
services.AddResponseCaching()
//Add Middleware:
app.UseResponseCaching();
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
[HttpGet]
[ResponseCache(Duration = 60, VaryByQueryKeys = new[] { "category" })]
public IActionResult GetProducts(string category)
{
// Implementation to retrieve and return products
}
}
Duration 屬性指定緩存持續時間(以秒為單位)(在本例中為 60 秒),而 VaryByQueryKeys 屬性指示應針對“category”查詢參數的不同值單獨緩存響應。
用戶輸入驗證
什么是用戶輸入驗證?
為什么要使用用戶輸入驗證?
您應該了解的 3 大理由(第 3 個是我的最愛):
數據完整性:通過驗證用戶輸入,可以強制執行業務規則、數據約束和特定格式要求。這有助于保持數據的完整性和一致性。安全漏洞防護:用戶輸入驗證通過檢測和拒絕惡意或格式錯誤的輸入,幫助保護 API 免受常見安全風險的影響。它確保您的 API 處理的數據值得信賴且可以安全處理。
錯誤處理:通過驗證用戶輸入,您可以在檢測到無效輸入時提供有意義的錯誤消息和響應。這有助于用戶理解和糾正他們的輸入,從而帶來更好的用戶體驗。
.NET Web API 示例
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
[HttpPost]
public IActionResult CreateProduct([FromBody] ProductDto product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Implementation to create a new product
}
}
// ProductDto.cs
public class ProductDto
{
[Required]
public string Name { get; set; }
[Range(0, 100)]
public int Quantity { get; set; }
// Other properties and validation attributes
}
異常處理
什么是異常處理?
為什么要使用異常處理?
其次,異常處理有助于將正常程序流與錯誤處理邏輯分離,使代碼更有條理、更可讀、更易于維護。它還通過將錯誤處理邏輯封裝在可重用的異常處理塊中來促進代碼重用。
防止未處理的異常:可以在異常向上傳播到調用堆棧并導致未處理的異常之前捕獲和處理異常,從而導致不可預知的行為或崩潰。
**“優雅”錯誤處理:**它有助于向客戶提供有意義的錯誤響應,從而改善用戶體驗。
調試和日志記錄:正確記錄的異常提供了對錯誤原因的寶貴見解,并有助于進行故障排除。
如何在 .NET 6 中實現全局異常處理中間件?
HandleError 操作,您可以在其中記錄錯誤并將標準化的錯誤響應返回給客戶端。
中間件:
[ApiController]
[Route("/error")]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : ControllerBase
{
[Route("{statusCode}")]
public IActionResult HandleError(int statusCode)
{
// Log the error and provide a meaningful error response
var errorResponse = new ErrorResponse
{
StatusCode = statusCode,
Message = "An error occurred."
};
return StatusCode(statusCode, errorResponse);
}
[Route("")]
public IActionResult HandleError()
{
// Log the error and provide a meaningful error response
var errorResponse = new ErrorResponse
{
StatusCode = 500,
Message = "An error occurred."
};
return StatusCode(500, errorResponse);
}
}
記錄 API
“Documenting API”是什么意思?
為什么要記錄 API?
我還可以給你兩個理由:
第三方集成:當您希望其他開發人員或組織將其應用程序或服務與您的 API 集成時,文檔至關重要。它是了解集成要求、數據格式和身份驗證機制的基礎。改進的可用性:有據可查的 API 提供了有關如何發出請求、處理響應和利用可用功能的清晰說明和示例。這樣可以更有效地使用 API,并減少錯誤或誤解的機會。
使用 Swagger 在 .NET 6 中記錄 API
Swagger 是一個廣泛用于 ASP.NET Web API 項目的庫。VIdeces 幾乎存在于您遇到的每個 API 項目中。了解更多: https://swagger.io/solutions/api-development/
將 Swagger 添加到依賴項注入中:
builder.Services.AddSwaggerGen(c =>{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
Add Middleware for Swagger and for Swagger UI to display and interact with generated documentation:
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1");
});
API 文檔變得簡單
使用 .NET 6 開發 Web API 項目的最佳實踐。通過遵循這些做法,您可以確保安全、可擴展且可維護的 API,以滿足用戶和客戶端的需求。雖然這些實踐是專門為 .NET 6 量身定制的,但其中許多實踐也可以應用于其他框架,從而為任何 API 開發工作提供寶貴的知識。
該文章在 2024/6/19 19:00:56 編輯過