目錄:
先決條件:介紹本文旨在全面概述程序員在創(chuàng)建 API 時(shí)應(yīng)遵循的最佳實(shí)踐。無論是使用 .NET 6 Web API 還是任何其他框架,這些做法對(duì)于提供設(shè)計(jì)良好且可靠的 API 都是必不可少的。
對(duì) API 進(jìn)行版本控制
什么是 API 版本控制?
API 是軟件。軟件的每個(gè)部分都需要在某個(gè)時(shí)候進(jìn)行更新。在 API 上創(chuàng)建一些更新時(shí),需要確保這些更改不會(huì)影響 API 使用者(用戶)。為確保這一點(diǎn),您需要引入 API 版本控制。
為什么需要 API 版本控制?
如果您的目標(biāo)是開發(fā)強(qiáng)大且可擴(kuò)展的 Web 應(yīng)用程序,請(qǐng)考慮從 Toptal 聘請(qǐng) ASP.NET 開發(fā)人員。憑借他們?cè)趧?chuàng)建高性能解決方案方面的深厚專業(yè)知識(shí),Toptal 的 ASP.NET 專業(yè)人員有能力提供滿足復(fù)雜業(yè)務(wù)需求的尖端應(yīng)用程序,確保頂級(jí)公司和初創(chuàng)公司有效地實(shí)現(xiàn)其技術(shù)目標(biāo)。
向后兼容性:它確??蛻舳丝梢岳^續(xù)使用舊版本,而新客戶端可以利用更新的功能。
API 演進(jìn):隨著 API 的演進(jìn),版本控制允許您引入新功能、棄用過時(shí)的功能并進(jìn)行改進(jìn),而不會(huì)中斷現(xiàn)有客戶端。
客戶端靈活性:不同的客戶端可能有不同的要求,或者可能需要特定版本的 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 屬性修飾操作方法,以指定每個(gè)方法的版本。
[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 開發(fā)變得輕而易舉!:D
使用正確的 HTTP 方法
什么是 HTTP 方法?
最常用的方法是:
使用正確的 HTTP 方法很重要,因?yàn)樗梢源_保遵守 REST 架構(gòu)風(fēng)格的原則,改進(jìn) API 設(shè)計(jì)和可維護(hù)性,通過實(shí)施適當(dāng)?shù)脑L問控制來增強(qiáng)安全性,促進(jìn)可伸縮性和緩存機(jī)制,并實(shí)現(xiàn)與 Web 上各種客戶端和服務(wù)器的互操作性和兼容性。
RESTful 原則:正確使用 HTTP 方法符合具象狀態(tài)傳輸 (REST) 的原則。RESTful API 利用這些方法的語義為客戶端創(chuàng)建統(tǒng)一且可預(yù)測(cè)的接口。
**語義清晰:**每個(gè) HTTP 方法都具有特定的含義,使您的 API 端點(diǎn)更加直觀和不言自明。開發(fā)人員可以根據(jù)所使用的 HTTP 方法輕松了解端點(diǎn)的用途和功能。
何時(shí)使用每種 HTTP 方法?
GET:使用 GET 從資源中檢索數(shù)據(jù)。它應(yīng)該不會(huì)對(duì)服務(wù)器產(chǎn)生任何副作用。POST:使用 POST 創(chuàng)建新資源。請(qǐng)求有效負(fù)載通常包含新資源的數(shù)據(jù),服務(wù)器為其分配唯一標(biāo)識(shí)符。
PUT:使用 PUT 更新現(xiàn)有資源或創(chuàng)建新資源(如果不存在)。請(qǐng)求負(fù)載包含要更新的資源的完整表示形式。
PATCH:使用 PATCH 對(duì)現(xiàn)有資源執(zhí)行部分更新。請(qǐng)求有效負(fù)載僅包括需要應(yīng)用于資源的更改。
DELETE:使用 DELETE 刪除由其唯一標(biāo)識(shí)符標(biāo)識(shí)的資源。
故事時(shí)間:
好像這還不夠,當(dāng)我無意中設(shè)置“PUT”方法而不是“DELETE”來刪除資源時(shí),我遇到了另一個(gè)錯(cuò)誤,導(dǎo)致數(shù)據(jù)持久且頑固。
.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
}
}
保護(hù) API
開發(fā) .NET 6 Web API 時(shí),API 安全性需要考慮幾個(gè)重要方面:
認(rèn)證:
.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"))
};
});
}
授權(quán)
// 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 庫(kù)實(shí)現(xiàn)此目的。
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
}
]
}
}
緩存響應(yīng)
什么是響應(yīng)緩存?
為什么要使用響應(yīng)緩存?
我將根據(jù)我的經(jīng)驗(yàn)向您解釋 3 個(gè)最有力的原潁�
改進(jìn)的性能:無需重復(fù)執(zhí)行相同的昂貴計(jì)算或數(shù)據(jù)庫(kù)查詢,而是從內(nèi)存或緩存存儲(chǔ)中快速提供緩存響應(yīng)。緩存響應(yīng)可縮短響應(yīng)時(shí)間并提高 API 的整體性能。節(jié)省帶寬:后續(xù)請(qǐng)求可以獲取緩存的響應(yīng),從而節(jié)省帶寬,而不是每次都傳輸整個(gè)響應(yīng)。緩存響應(yīng)可減少通過網(wǎng)絡(luò)發(fā)送的數(shù)據(jù)量。
減少服務(wù)器負(fù)載:通過提供緩存響應(yīng),服務(wù)器處理的請(qǐng)求更少,從而減少服務(wù)器負(fù)載并提高可伸縮性。這在處理高流量或資源密集型 API 時(shí)尤其有用。
.NET 實(shí)現(xiàn)
添加依賴項(xiàng):
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 屬性指定緩存持續(xù)時(shí)間(以秒為單位)(在本例中為 60 秒),而 VaryByQueryKeys 屬性指示應(yīng)針對(duì)“category”查詢參數(shù)的不同值單獨(dú)緩存響應(yīng)。
用戶輸入驗(yàn)證
什么是用戶輸入驗(yàn)證?
為什么要使用用戶輸入驗(yàn)證?
您應(yīng)該了解的 3 大理由(第 3 個(gè)是我的最愛):
數(shù)據(jù)完整性:通過驗(yàn)證用戶輸入,可以強(qiáng)制執(zhí)行業(yè)務(wù)規(guī)則、數(shù)據(jù)約束和特定格式要求。這有助于保持?jǐn)?shù)據(jù)的完整性和一致性。安全漏洞防護(hù):用戶輸入驗(yàn)證通過檢測(cè)和拒絕惡意或格式錯(cuò)誤的輸入,幫助保護(hù) API 免受常見安全風(fēng)險(xiǎn)的影響。它確保您的 API 處理的數(shù)據(jù)值得信賴且可以安全處理。
錯(cuò)誤處理:通過驗(yàn)證用戶輸入,您可以在檢測(cè)到無效輸入時(shí)提供有意義的錯(cuò)誤消息和響應(yīng)。這有助于用戶理解和糾正他們的輸入,從而帶來更好的用戶體驗(yàn)。
.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
}
異常處理
什么是異常處理?
為什么要使用異常處理?
其次,異常處理有助于將正常程序流與錯(cuò)誤處理邏輯分離,使代碼更有條理、更可讀、更易于維護(hù)。它還通過將錯(cuò)誤處理邏輯封裝在可重用的異常處理塊中來促進(jìn)代碼重用。
防止未處理的異常:可以在異常向上傳播到調(diào)用堆棧并導(dǎo)致未處理的異常之前捕獲和處理異常,從而導(dǎo)致不可預(yù)知的行為或崩潰。
**“優(yōu)雅”錯(cuò)誤處理:**它有助于向客戶提供有意義的錯(cuò)誤響應(yīng),從而改善用戶體驗(yàn)。
調(diào)試和日志記錄:正確記錄的異常提供了對(duì)錯(cuò)誤原因的寶貴見解,并有助于進(jìn)行故障排除。
如何在 .NET 6 中實(shí)現(xiàn)全局異常處理中間件?
HandleError 操作,您可以在其中記錄錯(cuò)誤并將標(biāo)準(zhǔn)化的錯(cuò)誤響應(yīng)返回給客戶端。
中間件:
[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?
我還可以給你兩個(gè)理由:
第三方集成:當(dāng)您希望其他開發(fā)人員或組織將其應(yīng)用程序或服務(wù)與您的 API 集成時(shí),文檔至關(guān)重要。它是了解集成要求、數(shù)據(jù)格式和身份驗(yàn)證機(jī)制的基礎(chǔ)。改進(jìn)的可用性:有據(jù)可查的 API 提供了有關(guān)如何發(fā)出請(qǐng)求、處理響應(yīng)和利用可用功能的清晰說明和示例。這樣可以更有效地使用 API,并減少錯(cuò)誤或誤解的機(jī)會(huì)。
使用 Swagger 在 .NET 6 中記錄 API
Swagger 是一個(gè)廣泛用于 ASP.NET Web API 項(xiàng)目的庫(kù)。VIdeces 幾乎存在于您遇到的每個(gè) API 項(xiàng)目中。了解更多: https://swagger.io/solutions/api-development/
將 Swagger 添加到依賴項(xiàng)注入中:
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 文檔變得簡(jiǎn)單
使用 .NET 6 開發(fā) Web API 項(xiàng)目的最佳實(shí)踐。通過遵循這些做法,您可以確保安全、可擴(kuò)展且可維護(hù)的 API,以滿足用戶和客戶端的需求。雖然這些實(shí)踐是專門為 .NET 6 量身定制的,但其中許多實(shí)踐也可以應(yīng)用于其他框架,從而為任何 API 開發(fā)工作提供寶貴的知識(shí)。
該文章在 2024/6/19 19:00:56 編輯過