Стоит ли дублировать валидацию на каждом слое?

Пишу простое 3-х слойное приложение, в один момент понял, что проверяю практически одно и тоже на каждом слое приложения. Стоит ли убирать лишние проверки? Разве функция не должна проверять все что получает и выкидывать подробный exception если пришло что-то не то?

Контроллер:

    [Authorize]
    public IActionResult GetDataList(int offset = 0, int amount = 0)
    {
        if (offset < 0 || amount < 0)
            return BadRequest();

        Guid userId = this.GetUserId();
        var dataList = dataService.GetDataList(userId, offset, amount); //Возможно стоит использовать OperationReslut?
        return Ok(dataList);
    }

Сервис:

    public IEnumerable<Data> GetDataList(Guid userId, int offset, int amount)
    {
        if (offset < 0 || amount < 0)    //Повторная проверка
            throw new ArgumentOutOfRangeException();

        if (userRepository.GetUser(userId) == null) //Пользователь прошел аутентификацию на уровне контроллера. Стоит убрать?
            throw new UserNotFoundException();      //Лишний запрос к бд

        IEnumerable<Data> dataList = dataQueries.GetDataList(userId, offset, amount);

        return dataList;
    }

Репозиторий:

    public IEnumerable<Data> GetDataList(Guid userId, int offset, int amount)
    {
        if (offset < 0 || amount < 0)    //Повторная проверка
            throw new ArgumentOutOfRangeException();

        //Стоит ли тут проверять существование пользователя с userId? Или просто сделать запрос и вернуть пустую коллекцию?
        //запрос к бд

        return dataList;
    }

Думаю просто убрать проверку на offset и count в репозитории.

С Проверкой на существование пользователя есть другая идея: создать что-то вроде сервиса для получения авторизованного пользователя. Интерфейс будет определен на сервисном слое, а реализация в слое представления

public interface IAuthenticationService
{
    Guid GetUserId();
    bool IsAuthenticated();
}

Тогда на сервисном слое будет понятно, что пользователь аутентифицирован, а значит точно находится в бд.

Что думаете по этому поводу? Спасибо за ответы!


Ответы (1 шт):

Автор решения: Aziz Umarov

Напишу своё субъективное мнение. Проверять одно и тоже не стоит на каждом слое. Вот только нужно определиться какой слой является общим для всех приложений в нем и валидировать. В моих приложениях слой БД изолирован и общение с БД происходит только через сервис данных. Я выбрасываю исключение в самой базе если данные легко валидируются в БД (дубликат, userid и тд) остальные на слое службы БД (символы, форматы ...)

→ Ссылка