.net - dotnet/meditr 最佳实践中的 REST 补丁
问题描述
我已经使用 PUT/POST 来更新我正在使用的应用程序,到目前为止这一直很简单。现在我正在开发一个 API,它应该公开一种更新数据库中数据的方法,我最初的想法是我可以替换该行(或部分替换它)。由于具有不同数据知识的不同应用程序需要更新,我认为使用 PATCH 操作而不是 PUT 可能是一个好主意。
我可以找到一些在控制器中实现更新的玩具示例,我对此并不感兴趣。
我使用与 jasontaylordev 的 Clean architecture 项目中相同的模式(CQRS w. Mediatr),所以我将在我的示例中使用它。
我有两个问题。
我不喜欢
JsonPatchDocument
对象应该到达我的处理程序,但我不知道如何避免这种情况。从控制器访问数据库不是一种选择。那么还有其他选择吗?(在我正在处理的项目中,nb Automapper 或类似的动态映射库都不是一个选项)如何从客户端应用程序(所有 dotnet 核心项目)构建 JsonPatch 对象。我认为如果我可以在具有两个属性和 if 和 的应用程序中拥有一个 DTO
Title
,Note
那么Title="test"
它Note=null
应该替换标题并删除注释。我可以以简单的方式映射到(奇怪的)补丁对象吗?[HttpPatch("{id}")] public async Task<ActionResult> Update(int id, UpdateTodoItemCommand command) { if (id != command.Id) { return BadRequest(); } await Mediator.Send(command); return NoContent(); } public class UpdateTodoItemCommand : IRequest { public int Id { get; set; } public JsonPatchDocument<TodoItemDto> Todo { get; set; } } public class TodoItemDto { public string Title { get; set; } public string Note { get; set; } } public class UpdateTodoItemCommandHandler : IRequestHandler<UpdateTodoItemCommand> { private readonly IApplicationDbContext _context; public UpdateTodoItemCommandHandler(IApplicationDbContext context) { _context = context; } public async Task<Unit> Handle(UpdateTodoItemCommand request, CancellationToken cancellationToken) { var entity = await _context.TodoItems.FindAsync(request.Id); if (entity == null) { throw new NotFoundException(nameof(TodoItem), request.Id); } var todoItemDto = new TodoItemDto(); todoItemDto.Title = entity.Title; todoItemDto.Note = entity.Note: todoItemDto.Todo.ApplyTo(request.Todo); entity.Title = todoItemDto.Title; entity.Note = todoItemDto.Note; await _context.SaveChangesAsync(cancellationToken); return Unit.Value; } }
解决方案
`JsonPatchDocument 是一个非常简单的对象,代表 JSON Patch RFC。它本质上是一组指令。如果您不想使用它,因为您不希望内置的 Microsoft 实现出现在您的处理程序中,那么您必须
- 创建您自己的类(例如 UpdateCommand,它本身与补丁文档非常相似;接受“替换”、“删除”等指令。
- 将补丁文档映射到此类的实例并通过 Mediatr 路由
- 重新创建已经从 asp.net 工具箱中提供的“修补机制”
这似乎需要做很多工作才能避免仅仅参考该参考。如果您愿意,您也许可以创建一个保存文档的命令,但这并没有多大作用。
我创建的一个实现只需要 JsonPatchDocument 并将其传递给应用补丁的策略类(该策略类与 Mediatr 扮演相同的角色,因此实际上是同一件事。然后我针对资源调用 Apply() 方法。
推荐阅读
- laravel - Vue共享组件未显示
- java - Youtube 和其他应用程序未在 Android 11 模拟器上显示
- rust - `HashMap::get_mut` 导致“返回对本地值的引用”,任何有效的解决方法?
- jquery - 使用 jQuery 让 facebook 喜欢计数
- bash - 如何在bash中获取目录中最大的文件?
- javascript - JavaScript:用小数 .0 消除数字
- python - PysimpleGUI 中的更新标签未发生
- javascript - 获取父级 (li) 的 id 及其内容 (span)。凯里奥
- reactjs - 在“Redux-Saga”中使用“React Navigation 6.0”重定向用户
- node.js - 应该如何部署我的 mern 应用程序