先决条件:
在开发 API 时,程序员除了实现基本功能外,还需要考虑各种因素。他们必须解决版本控制、安全性、性能、错误处理和文档等问题。通过结合这些领域的最佳实践,程序员可以确保其 API 的可靠性、可扩展性和可用性。
本文旨在全面概述程序员在创建 API 时应遵循的最佳实践。无论是使用 .NET 6 Web API 还是任何其他框架,这些做法对于提供设计良好且可靠的 API 都是必不可少的。
API 版本控制是一种用于管理 API 中的更改,同时保持与现有客户端的向后兼容性。它允许开发人员引入新功能、修复错误或对 API 进行其他修改,而不会影响现有集成的功能。
API 是软件。软件的每个部分都需要在某个时候进行更新。在 API 上创建一些更新时,需要确保这些更改不会影响 API 使用者(用户)。为确保这一点,您需要引入 API 版本控制。
您需要 API 版本控制,因为它可以确保兼容性,支持灵活地采用更改,提供受控和记录的修改,支持多个版本共存,并授予对 API 生命周期的精细控制,从而实现成功和高效的软件开发。
如果您的目标是开发强大且可扩展的 Web 应用程序,请考虑从 Toptal 聘请 ASP.NET 开发人员。凭借他们在创建高性能解决方案方面的深厚专业知识,Toptal 的 ASP.NET 专业人员有能力提供满足复杂业务需求的尖端应用程序,确保顶级公司和初创公司有效地实现其技术目标。
最重要的 3 个原因:
.NET 6 中有多种 API 版本控制方法。以下是两种常用的方法:
GET /products HTTP/1.1
Host: api.example.com
Accept: application/json
X-API-Version: 2
让我们以基于 URL 为例。首先,您需要安装一个软件包:
Microsoft.AspNetCore.Mvc.Versioning
然后,您需要在 Program.cs C# class:builder 中配置 API 版本控制。Services.AddApiVersioning(选项 =>
//Program.cs C# class:
builder.Services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
});
- ReportApiVersions -> API 响应将包含有关可用版本和用于当前请求
的版本的信息 - DefaultApiVersion -> 此选项设置默认 API 版本。
- AssumeDefaultVersionWhenUnspecified -> 设置为 true 时,如果客户端在请求中不包含版本,则 API 将使用 DefaultApiVersion 中指定的默认版本。
- ApiVersionReader -> 它决定如何从请求中提取 API 版本。在这种情况下,将从 URL 段读取 API 版本。
在 ProductsController 中,使用 MapToApiVersion 属性修饰操作方法,以指定每个方法的版本。
客户端可以通过将版本号附加到 URL 来访问不同版本的 API,例如 /v1/products 或 /v2/products。
[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
我建议您阅读Microsoft关于RESTful API版本控制的官方文章。
HTTP 方法(也称为 HTTP 谓词)是可以使用超文本传输协议 (HTTP) 对资源执行的标准化操作或操作。这些方法定义要对客户端请求的特定资源执行的操作类型。
最常用的方法是:
为什么使用正确的 HTTP 方法很重要?
使用正确的 HTTP 方法很重要,因为它可以确保遵守 REST 架构风格的原则,改进 API 设计和可维护性,通过实施适当的访问控制来增强安全性,促进可伸缩性和缓存机制,并实现与 Web 上各种客户端和服务器的互操作性和兼容性。
从我的角度来看,这 2 个是最重要的:
让我分享一下我在开发 .NET API 时使用 HTTP 方法的有趣体验。这一切都始于我错误地使用“GET”方法而不是“POST”来提交用户数据。这导致了滑稽的混淆和信息混淆。
好像这还不够,当我无意中设置“PUT”方法而不是“DELETE”来删除资源时,我遇到了另一个错误,导致数据持久且顽固。
经验教训:始终使用正确的 HTTP 方法,否则您会发现自己陷入了一个充满搞笑 API 事故的世界!
[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
}
}
请记住,根据要对资源执行的操作选择适当的 HTTP 方法,并遵循每种方法的准则和最佳做法。
保护 API 对于保护敏感数据、防止未经授权的访问和确保应用程序的完整性至关重要。它是指实施措施和实践的过程,以保护应用程序编程接口 (API) 免受未经授权的访问、数据泄露和其他安全风险。它涉及实施身份验证、授权、加密和其他安全机制,以确保 API 及其处理的数据的机密性、完整性和可用性。
开发 .NET 6 Web API 时,API 安全性需要考虑几个重要方面:
认证:
实施身份验证对于防止未经授权的访问和保护敏感资源至关重要。在 .NET 6 Web API 中,可以使用各种身份验证机制,例如 JSON Web 令牌 (JWT)、OAuth 或自定义身份验证方案。
.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"))
};
});
}
实施授权可确保用户对特定 API 端点或资源具有适当的访问权限。在 .NET 6 Web API 中,可以使用授权属性(如 [Authorize])或基于策略的授权来控制访问。
// 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
}
}
这是用于身份验证和授权的 YouTube 视频的绝佳播放列表。
速率限制有助于防止滥用、流量过大和拒绝服务 (DoS) 攻击。它确保了 API 资源的公平使用,并防止其不堪重负。在 API 中实施速率限制技术,例如为每个客户端、IP 地址或全局设置最大请求限制。
在 .NET 6 中,可以使用 AspNetCoreRateLimit 库实现此目的。
在Program.cs文件中添加依赖项:
services.AddMemoryCache();
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
并设置中间件:
app.UseIpRateLimiting();
您可以在 appsettings.json 文件中配置的速率限制规则:
{
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Forwarded-For",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
}
]
}
}
响应缓存涉及存储 API 请求的响应,并在再次发出相同请求时直接从缓存中提供该响应。通过缓存响应,您可以减少多次重新处理同一请求的需要,从而缩短响应时间并提高可伸缩性。
您应该使用响应缓存来最大限度地提高 API 的性能和可伸缩性,通过缩短响应时间来增强用户体验,提高整体响应能力,减轻服务器负载,优化网络带宽消耗并确保可用性,最终实现高效且高性能的 API 系统。
我将根据我的经验向您解释 3 个最有力的原因:
若要在 .NET 6 Web API 中启用响应缓存,可以使用内置的 ResponseCaching 中间件和 [ResponseCache] 属性。
添加依赖项:
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
}
}
在此示例中,ResponseCache 属性应用于 ProductsController 中的 GetProducts 操作。Duration 属性指定缓存持续时间(以秒为单位)(在本例中为 60 秒),而 VaryByQueryKeys 属性指示应针对“category”查询参数的不同值单独缓存响应。
Microsoft Learn 在响应缓存方面有很好的指南。
用户输入验证是在 API 中接受和处理用户输入的数据之前检查和验证数据的过程。它涉及验证输入的格式、类型和完整性,以防止常见的安全漏洞。您可以保护应用程序免受 SQL 注入、XSS(跨站点脚本)或命令注入攻击等漏洞的侵害。
您可能应该使用用户输入验证来确保数据完整性和准确性,通过防止潜在漏洞来增强应用程序的安全性,通过提供及时反馈和防止错误来改善用户体验,并最终创建可靠、安全和用户友好的应用程序。
您应该了解的 3 大理由(第 3 个是我的最爱):
[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
}
由于各种原因,例如编程错误、无效输入或外部依赖关系,可能会出现异常。通过适当的异常处理,您可以处理错误、从故障中恢复并向客户端提供响应。异常处理是管理和响应 API 代码执行期间发生的意外情况的过程。
首先,异常处理允许适当的错误管理和优雅地处理程序执行过程中可能出现的意外情况。通过捕获和处理异常,可以防止应用程序崩溃,并向用户提供有意义的错误消息或记录它们以进行故障排除。
其次,异常处理有助于将正常程序流与错误处理逻辑分离,使代码更有条理、更可读、更易于维护。它还通过将错误处理逻辑封装在可重用的异常处理块中来促进代码重用。
总结为3个原因:
在此示例中,全局异常处理中间件被添加到Program.cs文件中。它将未处理的异常重定向到 ErrorController 的 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);
}
}
在 Microsoft 的 Learn 平台上查找有关异常和最佳实践的更多异常处理最佳实践。
“记录 API”是指创建全面且信息丰富的文档的过程,这些文档描述了应用程序编程接口 (API) 的功能、用法和规范。当您创建 API 时,有人将使用该 API。使用 API 的人应该对将要使用的端点、请求和响应有直观的了解。良好的文档使开发人员能够轻松使用您的 API,减少集成时间,并提高开发人员的满意度。
您应该记录 API 的主要原因之一是为开发人员提供明确的说明和指南。
我还可以给你两个理由:
有一些工具和库可以帮助你记录你的 API。归根结底,你可以自己做(如果你没有很多时间,我不建议这样做)。
Swagger 是一个广泛用于 ASP.NET Web API 项目的库。VIdeces 几乎存在于您遇到的每个 API 项目中。了解更多: https://swagger.io/solutions/api-development/
配置 Swagger 非常简单。
将 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");
});
嫁给 Swagger 的样子?不用担心。Treblle 的实时自动生成 API 的功能可以选择打开它 Swagger,因为 Treblle 是 Open APISpec 计划的一部分。
自动生成的 API 文档 — Treblle
使用 .NET 6 开发 Web API 项目的最佳实践。通过遵循这些做法,您可以确保安全、可扩展且可维护的 API,以满足用户和客户端的需求。虽然这些实践是专门为 .NET 6 量身定制的,但其中许多实践也可以应用于其他框架,从而为任何 API 开发工作提供宝贵的知识。