在域驱动设计中应将输入验证放在何处? [英] where should put input validation in Domain Driven Design?

查看:75
本文介绍了在域驱动设计中应将输入验证放在何处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我们应该在什么地方进行输入验证(想象一个API调用发送输入以应用用户的空闲时间)。在服务层中注入验证类并在服务内部调用validate方法是否正确?还是最好将其放入基础架构层甚至域模型中?我只想看一个示例代码,该代码以域驱动设计方法对API的输入实施验证?如果我使用CQRS架构怎么办?

I was wondering where exactly we should put input validations(imagine an API call send input to apply free times of a user). Is it right to inject validation class in service Layer and call validate method inside service? or it's better to put it in the infrastructure layer or even in Domain model? I just wanted to see a sample code that's implement validation of input for an API in Domain-driven design approach? what if I use CQRS architecture?

推荐答案

我在DDD / CQRS项目中使用以下方法,项目结构为API层,域层,数据访问层,先验证来自UI或来自用户的所有输入数据,然后创建和调度命令以更新Domain的状态,然后我们将输入数据验证一次,一次出现在UI(Angular应用程序)上,第二次出现在Web API中层,如果数据有效,则将创建CQRS命令并将其分派,然后可以进行业务逻辑验证。为了进行验证,您可以使用 FastValidator FluentValidation

I use in my DDD/CQRS project following approach, structure of a project is API layer, Domain layer, Data Access layer, all input data from UI or from User are validated before, command are created and dispatched, to update the state of Domain, and we validate input data to times one is on the UI, (Angular app), and second one in Web API layer, if the data are valid the CQRS command are created and dispatched after that you can have Business logic validation. For validation you can use FastValidator or FluentValidation

更新:这是简单的示例我们有用于创建批处理实体的API。

UPDATE: Here is the simple example we have API for Create Batch Entity.

[HttpPost]
[Route("create")]  
public IHttpActionResult Create([FromBody] BatchEditModel model)
{
    var createCommand = model.Map<BatchEditModel, CreateBatchCommand>();

    var result = (OperationResult<int>) _commandDispatcher.Dispatch(createCommand);

    return Result(result);
}

您可以看到,用户输入数据将为 BatchEditModel

As you can see as user input data will be BatchEditModel.

所以我们有 BatchEditModelValidator ,其中包含输入数据验证:

so we have BatchEditModelValidator which contains input data validation:

public class BatchEditModelValidator : AbstractValidator<BatchEditModel>
{
    public BatchEditModelValidator()
    {
        RuleFor(x => x.Number).NotEmpty()
            .WithMessage(ValidatorMessages.MustBeSpecified);
        RuleFor(x => x.ClientId).GreaterThan(0)
            .WithMessage(ValidatorMessages.MustBeSpecified);
        RuleFor(x => x.EntryAssigneeId).GreaterThan(0)
            .WithMessage(ValidatorMessages.MustBeSpecified);
        RuleFor(x => x.ReviewAssigneeId).GreaterThan(0)
            .WithMessage(ValidatorMessages.MustBeSpecified);
        RuleFor(x => x.Description).NotEmpty()
            .WithMessage(ValidatorMessages.MustBeSpecified);
    }
}

此Validator将在BatchEditModel映射到之前执行CreateBatchCommand

this Validator will be executed before BatchEditModel will be mapped to CreateBatchCommand

,在 CreateBatchCommandHandler 中,我们有业务逻辑验证CheckUniqueNumber

and in CreateBatchCommandHandler we have Business logic validation CheckUniqueNumber

public OperationResult Handle(CreateBatchCommand command)
{
    var result = new OperationResult<int>();
    if (CheckUniqueNumber(result, command.ClientId, command.Number))
    {
        if (result.IsValid)
        {
            var batch = _batchFactory.Create(command);
            _batchRepository.Add(batch);
            _batchRepository.Save();

            result.Value = batch.Id;
        }
    }
    return result;
}

这篇关于在域驱动设计中应将输入验证放在何处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆