
ASP.NET Web API快速入門介紹
[ApiController]
publicclassUsersController : ControllerBase
{
privatereadonly IUserRepository _userRepository;
public UsersController(IUserRepository userRepository)
{
_userRepository = userRepository;
}
// GET: api/Users
[HttpGet]
public ActionResult<List<User>> Get()
{
return _userRepository.GetAll();
}
// GET: api/Users/5
[HttpGet("{id}")]
public ActionResult<User> Get(int id)
{
var user = _userRepository.GetById(id);
if (user == null)
{
return NotFound();
}
return user;
}
// POST: api/Users
[HttpPost]
public IActionResult Create([FromBody] User newUser)
{
_userRepository.Add(newUser);
return CreatedAtAction(nameof(Get), new { id = newUser.Id }, newUser);
}
// PUT: api/Users/5
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody] User updatedUser)
{
var existingUser = _userRepository.GetById(id);
if (existingUser == null)
{
return NotFound();
}
existingUser.Name = updatedUser.Name;
existing美高梅集團游戲大廳官方網站_歡迎您!Email = updatedUser.Email;
_userRepository.Update(existingUser);
return NoContent();
}
// DELETE: api/Users/5
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var existingUser = _userRepository.GetById(id);
if (existingUser == null)
{
return NotFound();
}
_userRepository.Delete(id);
return Noflare美高梅集團游戲大廳官方網站_歡迎您!;
}
}
為API端點使用清晰、一致的命名規范。資源(名詞)應該清晰命名,集合使用復數名詞,單個實體使用單數名詞。
在REST中,客戶端和服務器之間的交互在請求之間是無狀態的。每個從客戶端到服務器的請求必須包含理解并完成請求所需的所有信息(服務器在請求之間不存儲客戶端上下文)。
HTTP狀態碼提供關于HTTP請求結果的即時反饋。
內容協商是服務器根據客戶端的能力和偏好(在請求頭中表示)選擇適當的響應內容類型的過程。這允許服務器根據客戶端的需求以不同格式提供同一資源。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true; // 默認為false
})
.AddXmlSerializerFormatters(); // 添加XML支持
}
您可以通過發送具有不同Accept頭的HTTP GET請求來測試內容協商功能。
請求JSON響應:
GET /users/1 HTTP/1.1
Host: localhost:5000
Accept: application/json
請求XML響應:
GET /users/1 HTTP/1.1
Host: localhost:5000
Accept: application/xml
版本控制有助于在不破壞現有客戶端的情況下管理API的更改。
實現認證和授權,并確保數據通過HTTPS傳輸。驗證所有輸入以避免SQL注入和其他攻擊。
publicclassBasicAuthAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(AuthorizationFilterContext context)
{
string authHeader = context.HttpContext.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
// 提取憑據
}
else
{
context.Result = new UnauthorizedResult();
}
}
}
提供清晰、一致的錯誤消息和HTTP狀態碼。
public ActionResult<User> Get(int id)
{
try
{
var user = UserRepository.GetById(id);
if (user == null) return NotFound("User not found.");
return user;
}
catch (Exception ex)
{
return StatusCode(500, "Internal server error: " + ex.Message);
}
}
使用Swagger(OpenAPI)等工具自動生成API文檔。
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
緩存是RESTful API的重要組成部分,它通過減少服務器負載和降低響應延遲顯著提高了性能和可擴展性。在RESTful服務中,響應可以明確標記為可緩存或不可緩存,這有助于客戶端和中間代理了解是否應該存儲響應數據并在后續請求中重用它。
[ApiController]
[Route("[controller]")]
publicclassDataController : ControllerBase
{
[HttpGet("{id}")]
public IActionResult GetData(int id)
{
var data = new { Id = id, Value = "Sample Data" };
// 設置緩存頭
HttpContext.Response.Headers["Cache-Control"] = "public,max-age=3600";
HttpContext.Response.Headers["Expires"] = DateTime.UtcNow.AddHours(1).ToString();
return Ok(data);
}
}
在上面的示例中,當調用GetData方法時,它會設置兩個與緩存相關的HTTP頭。
public
:表示響應可以被任何緩存存儲。max-age=3600:指定響應在3600秒(1小時)內被認為是新鮮的。有時,您可能希望使用服務器驗證緩存的數據??梢允褂肊Tag或Last-Modified等頭來做到這一點。然后,服務器可以決定如果內容沒有改變,就發送304 Not Modified,從而節省帶寬。
Vary
頭可以用來處理基于請求的某些方面(如Accept-Encoding或Accept-Language頭)而變化的響應緩存。
為了防止API被過度使用或濫用,實施速率限制。這限制了用戶在特定時間段內可以發出的請求數量。
publicclassRateLimitingMiddleware
{
privatereadonly RequestDelegate _next;
privatestatic Dictionary<string, DateTime> _requests = new Dictionary<string, DateTime>();
privatereadonlyint _requestLimit;
privatereadonly TimeSpan _timeSpan;
public RateLimitingMiddleware(RequestDelegate next, int requestLimit, TimeSpan timeSpan)
{
_next = next;
_requestLimit = requestLimit;
_timeSpan = timeSpan;
}
public async Task InvokeAsync(HttpContext context)
{
var ipAddress = context.Connection.RemoteIpAddress.ToString();
if (_requests.ContainsKey(ipAddress))
{
if (DateTime.UtcNow - _requests[ipAddress] < _timeSpan)
{
context.Response.StatusCode = 429; // Too Many Requests
await context.Response.WriteAsync("Rate limit exceeded. Try again later.");
return;
}
else
{
_requests[ipAddress] = DateTime.UtcNow;
}
}
else
{
_requests.Add(ipAddress, DateTime.UtcNow);
}
await _next(context);
}
}
接下來,您需要在Startup.cs
或Program.cs
文件中注冊此中間件,具體取決于您使用的ASP.NET Core版本。以下是如何在Startup.cs
中注冊它的方法。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 其他中間件注冊...
// 使用每小時每個IP 100個請求的限制注冊速率限制中間件
app.UseMiddleware<RateLimitingMiddleware>(100, TimeSpan.FromHours(1));
// 繼續處理管道
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
構建現代RESTful API不僅僅是處理請求和響應。它還需要仔細考慮設計原則、安全性、性能和可用性。通過遵循這些標準和最佳實踐,開發人員可以創建健壯、可擴展和安全的API,這不僅有利于API開發人員,而且確保API最終用戶有一個愉快和高效的體驗。
文章轉自微信公眾號@技術探索驛站