.NET?6開發(fā)TodoList應用之實現(xiàn)DELETE請求與HTTP請求冪等性
需求
先說明一下關于原本想要去更新的PATCH請求的文章,從目前試驗的情況來看,如果是按照.NET 6的項目結構(即只使用一個Program.cs完成程序初始化),那微軟官方給出的文檔目前還沒有對應地更新,按照之前的方式進行JsonPatch的配置是不行的,目前已經有人在Github微軟的官方文檔Repo下提了ISSUE: .NET 6: JsonPatch in ASP.NET Core web API。并且因為PATCH的使用頻率并不高,所以我暫時跳過那篇,先把進度繼續(xù)往后走,看微軟什么時候把這個issue解決一下我再看情況把PATCH那一節(jié)補上。
本文我們來看最后一個常用HTTP請求類型:DELETE。
目標
實現(xiàn)并驗證應用正確處理DELETE請求。并對HTTP請求的冪等性做簡單的介紹。
原理與思路
經過關于Create、Update、Get的實現(xiàn),對于Delete的實現(xiàn)我們的思路是很清晰的。我們需要創(chuàng)建Delete的Command及其Handler,然后在Controller中通過Mediatr發(fā)送請求即可。
實現(xiàn)
在Application/TodoList下新建DeleteTodoList文件夾,并新建DeleteTodoListCommand:
DeleteTodoListCommand.cs
using MediatR;
using TodoList.Application.Common.Exceptions;
using TodoList.Application.Common.Interfaces;
namespace TodoList.Application.TodoLists.Commands.DeleteTodoList;
public class DeleteTodoListCommand : IRequest
{
public Guid Id { get; set; }
}
public class DeleteTodoListCommandHandler : IRequestHandler<DeleteTodoListCommand>
{
private readonly IRepository<Domain.Entities.TodoList> _repository;
public DeleteTodoListCommandHandler(IRepository<Domain.Entities.TodoList> repository)
{
_repository = repository;
}
public async Task<Unit> Handle(DeleteTodoListCommand request, CancellationToken cancellationToken)
{
var entity = await _repository.GetAsync(request.Id);
if (entity == null)
{
throw new NotFoundException(nameof(TodoList), request.Id);
}
await _repository.DeleteAsync(entity,cancellationToken);
// 對于Delete操作,演示中并不返回任何實際的對象,可以結合實際需要返回特定的對象。Unit對象在MediatR中表示Void
return Unit.Value;
}
}
在Controller中添加Delete的接口處理:
TodoListController.cs
// 省略其他...
[HttpDelete("{id:guid}")]
public async Task<ApiResponse<object>> Delete(Guid id)
{
return ApiResponse<object>.Success(await _mediator.Send(new DeleteTodoListCommand { Id = id }));
}
這里可能值得強調的是關于EntityFrameworkCore中對于關聯(lián)實體DELETE操作的處理方式:
打開Infrastructure/Migrations文件夾,我們可以在遷移領域實體的那次Migration生成的.Designer.cs文件中發(fā)現(xiàn)這樣一段配置:
// 省略其他...
modelBuilder.Entity("TodoList.Domain.Entities.TodoItem", b =>
{
b.HasOne("TodoList.Domain.Entities.TodoList", "List")
.WithMany("Items")
.HasForeignKey("ListId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("List");
});
可以看到在OnDelete中配置的是DeleteBehavior.Cascade行為模式,關于DeleteBehavior,可以參考Referential Constraint Action Options。實際上總共有七種可以設置的行為模式:
- DeleteBehavior.Cascade
- DeleteBehavior.NoAction
- DeleteBehavior.Restrict
- DeleteBehavior.SetNull
- DeleteBehavior.ClientCascade
- DeleteBehavior.ClientNoAction
- DeleteBehavior.ClientSetNull
關于這七種DeleteBehavior,可以參考這篇博文:Entity Framework Core 關聯(lián)刪除,博主在其中進行了比較詳細的實驗和總結。
可以根據實際需要去顯式地配置DeleteBehavior。另外,習慣觀察生成的Migrations文件,也是學習EFCore一些慣例或者說默認配置的很好的方法。
驗證
啟動Api項目,發(fā)送DELETE請求:
請求

響應

并且從數據庫里我們以可以發(fā)現(xiàn),這條TodoList下包含的TodoItem也被一同刪除了。
總結
到此為止HTTP常用的四大請求我們已經通過幾個例子講完了,關于HEAD請求OPTION請求以及遺留的PATCH請求后面會寫完。下一篇文章開始我們一起學習如何使用FluentValidation來進行請求參數校驗。
關于HTTP請求冪等性的介紹
首先明確兩個概念:
1.什么叫做HTTP請求是否安全:如果我們執(zhí)行請求后,對應的資源實體不發(fā)生改變,我們稱這個請求是安全的;
2.什么叫做HTTP請求是否冪等:對于執(zhí)行請求后產生的副作用(即指如果請求不安全,則稱其會產生副作用),請求執(zhí)行一次和執(zhí)行多次的副作用是相同的,我們稱這個請求是冪等的,很顯然安全的請求一定是冪等的。
了解了這兩個概念后,我們直接來看這張表格,快速地對HTTP請求的安全性和冪等性有一個認識。

鑒于PATCH方法并不常用,那么重點需要關注的主要就是POST請求,以及一部分的PUT請求(比如更新的字段是在當前字段值的基礎上進行計算而新得出這種場景,實際就不是冪等的,但是我們一般不推薦在Update時做這種類型的操作,更推薦的是把計算邏輯前置到接口響應處理前,以整體設置值的方式去Update實體)。一般而言POST請求是用來創(chuàng)建資源的,如果不采取某種方式來保證執(zhí)行結果的實際冪等性,那么該請求產生的副作用將是難以控制和處理的。
如何保證接口的冪等性?
正式因為并非所有的HTTP請求(在這里我們可以泛化到任意類型的接口請求)都是冪等的,而不管是應用程序內的容錯還是服務之間因為分區(qū)導致的對請求的冪等性更為嚴格的要求(尤其是在分布式系統(tǒng)中,對于分區(qū)導致的請求重試的場景),我們需要在設計和實現(xiàn)接口的時候,把冪等性設計考慮進來,提高接口的魯棒性。
總體來說,實現(xiàn)接口的冪等性有兩種思路:一種是通過代碼邏輯去限制重復調用出現(xiàn)的副作用;第二種是通過Token唯一性來保證同一個請求不會被調用多次。
通過代碼邏輯去限制副作用的實現(xiàn)方式有很多種:從前端/界面的層次上去人為限制請求的重復發(fā)送(比如按鈕置灰禁止點擊之類的),通過在數據庫層面應用鎖或使用唯一索引,通過在邏輯執(zhí)行過程中應用鎖等方式。這種方式只能針對一些通過滿足某些判斷進行的邏輯實現(xiàn),有其局限性。
通過Token唯一性保證冪等的思路大致是這樣:生成全局唯一的Token保存下來,并在前端頁面獲取保存,發(fā)送請求時連同Token一起發(fā)到后端,后端先進行Token校驗,校驗通過發(fā)送實際請求或執(zhí)行邏輯,完成后刪除舊Token并生成新Token,那么前端下次攜帶保存的舊Token來請求時,因為Token校驗不通過而拒絕繼續(xù)執(zhí)行。這種方式就好比短信驗證碼,只有第一次攜帶這個驗證碼請求時會成功,后端判斷第一次請求有效后就會把這個驗證碼置為無效,下次你就無法攜帶相同的驗證碼繼續(xù)發(fā)起請求了。例子不是特別恰當,但是可以類比著進行理解。?
到此這篇關于.NET 6開發(fā)TodoList應用之實現(xiàn)DELETE請求與HTTP請求冪等性的文章就介紹到這了,更多相關.NET 6實現(xiàn)DELETE請求與HTTP請求冪等性內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- .NET 6開發(fā)TodoList應用之實現(xiàn)查詢分頁
- .NET 6開發(fā)TodoList應用之實現(xiàn)ActionFilter
- .NET 6開發(fā)TodoList應用之實現(xiàn)接口請求驗證
- .NET 6開發(fā)TodoList應用之實現(xiàn)PUT請求
- .NET 6開發(fā)TodoList應用之實現(xiàn)全局異常處理
- .NET 6開發(fā)TodoList應用之使用AutoMapper實現(xiàn)GET請求
- .NET?6開發(fā)TodoList應用之實現(xiàn)Repository模式
- .NET?6開發(fā)TodoList應用之使用MediatR實現(xiàn)POST請求
- .NET 6開發(fā)TodoList應用引入數據存儲
- .NET?6開發(fā)TodoList應用引入第三方日志庫
- .NET 6開發(fā)TodoList應用實現(xiàn)結構搭建
- .NET?6開發(fā)TodoList應用實現(xiàn)系列背景
- 使用.NET?6開發(fā)TodoList應用之引入數據存儲的思路詳解
- 使用.NET?6開發(fā)TodoList應用之領域實體創(chuàng)建原理和思路
- .NET?6開發(fā)TodoList應用之請求日志組件HttpLogging介紹
相關文章
Entity Framework使用DbModelBuilder API創(chuàng)建表結構
這篇文章介紹了Entity Framework使用DbModelBuilder API創(chuàng)建表結構的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-03-03
Visual Studio(VS2017)配置C/C++ PostgreSQL9.6.3開發(fā)環(huán)境
這篇文章主要為大家詳細介紹了Visual Studio(VS2017)配置C/C++,PostgreSQL9.6.3開發(fā)環(huán)境,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
MVC+EasyUI+三層新聞網站建立 實現(xiàn)登錄功能(四)
這篇文章主要為大家詳細介紹了MVC+EasyUI+三層新聞網站建立的第四篇,教大家實現(xiàn)登錄功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
.NET Core利用動態(tài)代理實現(xiàn)AOP(面向切面編程)
用動態(tài)代理可以做AOP(面向切面編程),進行無入侵式實現(xiàn)自己的擴展業(yè)務,調用者和被調用者之間的解耦,提高代碼的靈活性和可擴展性。本文將為大家詳細介紹實現(xiàn)的方法,感興趣的可以學習一下2022-01-01
SQL Server 2008 R2:error 26 開啟遠程連接詳解
本篇文章小編為大家介紹,SQL Server 2008 R2:error 26 開啟遠程連接詳解。需要的朋友參考下2013-04-04
.NET下通過HttpListener實現(xiàn)簡單的Http服務
這篇文章主要為大家詳細介紹了.NET下通過HttpListener實現(xiàn)簡單Http服務的相關資料,感興趣的小伙伴們可以參考一下2016-09-09

