[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美高梅集團游戲大廳官方網站_歡迎您!;
}
}

二、資源命名規范

2.1 清晰一致的命名

為API端點使用清晰、一致的命名規范。資源(名詞)應該清晰命名,集合使用復數名詞,單個實體使用單數名詞。

示例

三、無狀態性

3.1 請求之間的無狀態交互

在REST中,客戶端和服務器之間的交互在請求之間是無狀態的。每個從客戶端到服務器的請求必須包含理解并完成請求所需的所有信息(服務器在請求之間不存儲客戶端上下文)。

關鍵點

四、使用狀態碼

4.1 HTTP狀態碼的作用

HTTP狀態碼提供關于HTTP請求結果的即時反饋。

五、內容協商

5.1 根據客戶端需求選擇響應格式

內容協商是服務器根據客戶端的能力和偏好(在請求頭中表示)選擇適當的響應內容類型的過程。這允許服務器根據客戶端的需求以不同格式提供同一資源。

示例代碼

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

六、版本控制

6.1 管理API變更

版本控制有助于在不破壞現有客戶端的情況下管理API的更改。

示例

七、安全實踐

7.1 實現認證和授權

實現認證和授權,并確保數據通過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();
}
}
}

八、錯誤處理

8.1 提供清晰一致的錯誤信息

提供清晰、一致的錯誤消息和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);
}
}

九、文檔

9.1 自動生成API文檔

使用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");
});
}

十、緩存

10.1 提高性能和可擴展性

緩存是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頭。

10.2 驗證緩存數據

有時,您可能希望使用服務器驗證緩存的數據??梢允褂肊Tag或Last-Modified等頭來做到這一點。然后,服務器可以決定如果內容沒有改變,就發送304 Not Modified,從而節省帶寬。

10.3 處理基于請求變化的緩存

Vary頭可以用來處理基于請求的某些方面(如Accept-Encoding或Accept-Language頭)而變化的響應緩存。

十一、速率限制

11.1 防止API濫用

為了防止API被過度使用或濫用,實施速率限制。這限制了用戶在特定時間段內可以發出的請求數量。

示例代碼

步驟1:創建速率限制中間件
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);
}
}
步驟2:注冊中間件

接下來,您需要在Startup.csProgram.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最終用戶有一個愉快和高效的體驗。

文章轉自微信公眾號@技術探索驛站

上一篇:

如何用 OpenAPI 在 Express 中構建更好的 API

下一篇:

C#與C++交互開發系列:跨進程通信之使用基于HTTP協議的REST風格的API
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費