首页 > 解决方案 > dotnet/meditr 最佳实践中的 REST 补丁

问题描述

我已经使用 PUT/POST 来更新我正在使用的应用程序,到目前为止这一直很简单。现在我正在开发一个 API,它应该公开一种更新数据库中数据的方法,我最初的想法是我可以替换该行(或部分替换它)。由于具有不同数据知识的不同应用程序需要更新,我认为使用 PATCH 操作而不是 PUT 可能是一个好主意。

我可以找到一些在控制器中实现更新的玩具示例,我对此并不感兴趣。

我使用与 jasontaylordev 的 Clean architecture 项目中相同的模式(CQRS w. Mediatr)所以我将在我的示例中使用它。

我有两个问题。

  1. 我不喜欢JsonPatchDocument对象应该到达我的处理程序,但我不知道如何避免这种情况。从控制器访问数据库不是一种选择。那么还有其他选择吗?(在我正在处理的项目中,nb Automapper 或类似的动态映射库都不是一个选项)

  2. 如何从客户端应用程序(所有 dotnet 核心项目)构建 JsonPatch 对象。我认为如果我可以在具有两个属性和 if 和 的应用程序中拥有一个 DTO TitleNote那么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;
     }
    }
    

标签: .net.net-corepatchmediatr

解决方案


`JsonPatchDocument 是一个非常简单的对象,代表 JSON Patch RFC。它本质上是一组指令。如果您不想使用它,因为您不希望内置的 Microsoft 实现出现在您的处理程序中,那么您必须

  • 创建您自己的类(例如 UpdateCommand,它本身与补丁文档非常相似;接受“替换”、“删除”等指令。
  • 将补丁文档映射到此类的实例并通过 Mediatr 路由
  • 重新创建已经从 asp.net 工具箱中提供的“修补机制”

这似乎需要做很多工作才能避免仅仅参考该参考。如果您愿意,您也许可以创建一个保存文档的命令,但这并没有多大作用。

我创建的一个实现只需要 JsonPatchDocument 并将其传递给应用补丁的策略类(该策略类与 Mediatr 扮演相同的角色,因此实际上是同一件事。然后我针对资源调用 Apply() 方法。


推荐阅读