Where To Place Your Validation Code In Clean Architecture

แชร์
ฝัง
  • เผยแพร่เมื่อ 13 ต.ค. 2024

ความคิดเห็น • 102

  • @MilanJovanovicTech
    @MilanJovanovicTech  ปีที่แล้ว +5

    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt

    • @mrwalkan
      @mrwalkan ปีที่แล้ว +1

      Thank you for such an awesome video❤

  • @unhandledexception1948
    @unhandledexception1948 ปีที่แล้ว +3

    never dissappointed with Milan's videos.... super content :-)

  • @nove1398
    @nove1398 ปีที่แล้ว +2

    I think this is a pretty neat approach, I never used it before. I will definitely give it a try in one of my projects.

  • @thomasjespersen
    @thomasjespersen ปีที่แล้ว +2

    Love that you keep coming back to the same subjects. 💪
    As you know, I'm also using this in PlatformPlatform, but I'm struggling a bit with the proper separation of input validation versus domain validation. For example, if I validate the length or format of, say, a user's email address; is input validation sufficient? What if another part of my system is changing that property? I'm finding it hard to trust that validation is only done in the MediatR pipeline behavior. It could be as simple as ensuring the same validation logic is shared between the CreateCommand and UpdateCommand.
    How would you enforce validation in a complex domain?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      If all your incoming requests flow through the MediatR pipeline - than input validation is sufficient. If you have other components trying to modify data outside of the pipeline, you'll need to do some duplication. Small price to pay. I also differentiate between input validation and business validation. Business validation is part of the use case.

  • @saddamhossaindotnet
    @saddamhossaindotnet ปีที่แล้ว +2

    Excellent and highly informative video. Thank you, Milan!

  • @hfarukatasoy
    @hfarukatasoy ปีที่แล้ว +1

    Thank you for sharing Milan

  • @celsochaves_
    @celsochaves_ ปีที่แล้ว +1

    Another great video!! Thanks Milan!!

  • @kodindoyannick5328
    @kodindoyannick5328 7 หลายเดือนก่อน +1

    Thank you Milan. Super content but not simple for me.

  • @CodingWithFerry
    @CodingWithFerry ปีที่แล้ว +2

    Milan, thanks for the video. This is something I'm definitely going to use.
    I'm curious though why you placed the email uniqueness check into a validator and not inside the Command Handler. In general, can you explain which kind of 'checks' are placed in which location (Validators, CommandHandlers, Domain Layer or even in the database configuration)? Right now, I'm often struggling where the same rule is checked multiple times in the flow of my application or where business rules / application rules are not 'together'.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +2

      It's there from an older video, and I wanted to highlight async validation. So it's debatable where the proper place to put it is. I would generally lean towards only doing synchronous, input validation in command validators. And any business validation (touch the DB, or other services) in the handlers.

  • @16M-w4y
    @16M-w4y ปีที่แล้ว +1

    Thanks for the nice video
    Can you explain in a later video about the site
    Repository (interface and implementation)
    Generate Repository
    services
    Model
    Data access(DbContext)
    also which/where I can use DbContext to deal with Data Base

  • @DavidsonBruno
    @DavidsonBruno 11 หลายเดือนก่อน +1

    Hi Milan! I'm a big fan of your videos, thank you for this one! I have a question for you: in that approach your controller request model becomes the command model? if so, how do you handle with the need of keep your primitive fields as nullable types to avoid the possibility of AspDotNet parse an uninformed required value as a default value? I don't like the fact of my command having nullabe fields just for the input validation. For me, It should be in a validated version of itself. What do you think about it?

    • @MilanJovanovicTech
      @MilanJovanovicTech  11 หลายเดือนก่อน +1

      I think the better approach is having Request types and Command types. And then mapping from Request -> Comand

    • @DavidsonBruno
      @DavidsonBruno 11 หลายเดือนก่อน

      @@MilanJovanovicTech Perfect. In this case I would change my ValidationPipelineBehaviour to handle with the request types and maybe would return the mapped command from that, isn't it? And in my controller I would have two calls to mediator, one for my request type and another for my command obtained from the first one.
      An another approach I was thinking is not use the Pipeline Behaviour, inject the specific validation for the request type and call ValidateAndThrow method, making my Exception Handler handle it.

  • @zikkrype
    @zikkrype 11 วันที่ผ่านมา

    Hi there. I've been thinking about validation recently. For example, let's assume we have Minimal API application. Very often request contracts do not match mediatr commands models. So there could be inconsistency with property names etc. (Example: property named EmailAddress in one class and Email another class), which could cause inconveniences in error messages. Maybe instead of keeping consistency with property names we should implement mechanism to validate request models and not business models?

    • @MilanJovanovicTech
      @MilanJovanovicTech  11 วันที่ผ่านมา

      It makes sense, but it's only worth it if the UI will somehow use this info to display messages. Most of the time, the error messages are intended for developer using the API. So it should be intuitive enough already.

  • @alichoobdar9030
    @alichoobdar9030 ปีที่แล้ว +1

    Great. What do you recommmend about business validations?

  • @jsquebec
    @jsquebec ปีที่แล้ว +1

    Thank you very much for this excellent advice. However, I don't understand why we would add a validation that queries the database if we have already placed a unique index on the email column. At the time of saving, if the email already exists, won't the database raise an exception? Or is it just for this example?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      In most cases you wouldn't - but I wanted to show an example.

  • @hugoconceicao9062
    @hugoconceicao9062 5 หลายเดือนก่อน

    One possible trouble, the validation is made over CreateCustomerCommand and not over CreateCustomerRequest, which may not have the exact same properties. Then you show the property name/path's command and not the request property/path.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      That's a valid concern. However, we can provide custom error codes/error properties when generating the validation failures.

  • @PedroPabloCalvoMorcillo
    @PedroPabloCalvoMorcillo ปีที่แล้ว +3

    Great! What if we don't want to throw exceptions? I'm thinking about an MVC app showing validation errors in an HTML view.

    • @ИванИванов-о8я9с
      @ИванИванов-о8я9с ปีที่แล้ว +1

      Great question. I could not implement pipelines to add errors to modelState. I use IValidator in controller actions.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      Figure out a way to return a result from the pipeline. You'll probably need an envelope of some sort for all requests to make it work.

    • @PedroPabloCalvoMorcillo
      @PedroPabloCalvoMorcillo ปีที่แล้ว +1

      @@ИванИванов-о8я9с You can return all validation errors from the pipeline and add them to the Controller's ModelState in your controller (you can use an extension method, for example).

    • @meowzhin
      @meowzhin ปีที่แล้ว

      Drop cqrs and mediatr and you can integrate fluentvalidation with MVC pipeline directly, returning a custom page with your errors.

    • @PedroPabloCalvoMorcillo
      @PedroPabloCalvoMorcillo ปีที่แล้ว

      @@meowzhin Yes. You can also integrate FluentValidation with MediatR pipeline.

  • @oldwhitowl
    @oldwhitowl ปีที่แล้ว +1

    Great video sir. I'm currently looking at migrating to mediatr, i have used it in the past. Currently i use filters and fluentvalidation to automatically validate dtos for each api request. Using mediatr would mean the validation is performed later in the process. It seems wrong to remove the api validation and move it to my application layer via mediatr. But i like the mediatr method. Any thought's from anyone on this?!

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      The only thing I place in my API endpoints is packaging up the request into a command and passing it via MediatR. So I consider my request pipeline - which has validation - to be the actual entrypoint. Might also want to take a look at FastEndpoints.

    • @oldwhitowl
      @oldwhitowl ปีที่แล้ว

      @MilanJovanovicTech thanks Milan, I have briefly looked at fast endpoints in the past which I quite liked but was concerned about support issues with other developers in my team. I have come to the same conclusion regarding validation, my controller just forward the requests so I think I will move the validations to application layer. Do you have any videos on mediatr with a cache pipeline? I've implemented one using lazycache but I ideally need something with tagging or some way to group responses. Keep up the great work sir!

  • @alesdvorakcz
    @alesdvorakcz ปีที่แล้ว +1

    Validating commands make sense but how to propagate input validation into Swagger? Add another layer of validation (or manually describing which property is required, etc.) for open api seems redundant. It would be nice to connect it homehow.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      Do you need anything other than basic ASP.NET validation on the input side?

    • @alesdvorakcz
      @alesdvorakcz ปีที่แล้ว

      @@MilanJovanovicTech What I wanted to point out is, if you validate "CreateCustomerRequest" instead of "CreateCustomerCommand" you can easily propagate validation constrains into Swagger. Then for example, if you generate an api client from Swagger document, it will automatically know which properties are required, what are min/max lengths, etc.

  • @matthewrossee
    @matthewrossee 11 หลายเดือนก่อน +1

    What is the validation context for? What would be the difference if we just called _validators.Select(validator => validator.Validate(request, cancellationToken))?

    • @MilanJovanovicTech
      @MilanJovanovicTech  11 หลายเดือนก่อน +1

      It should allow you to share data on the context between validators. Let me see if I can find a good example.

  • @maflend2762
    @maflend2762 ปีที่แล้ว +1

    With the use of a mediator, everything is quite beautiful and easy. But what if we have business logic on services? Without CQRS

  • @zheniachubarov3384
    @zheniachubarov3384 19 วันที่ผ่านมา

    I have question about such cases, when you have to extract something from database, check if it is not null and if it's not, that do smth. For example, when we want to update user by id, firstly we try to get the user from db, than we check for null and depending on results, doing smth or throwing an exception.
    So my question is where am I supposed to put such kind of validation logic?
    For example, if I put such check into fluent validator, I will have to put logic to get user from db into service, because I need to get user to work with it. So with such approach we have one more call to the DB. On the other hand, if we put check whether user is null or not into service, we slightly overwhelm the service method, but at the same time we will have only one call to the DB.
    So, what would be better?

    • @MilanJovanovicTech
      @MilanJovanovicTech  19 วันที่ผ่านมา

      I typically place that directly in the use case, so that the logic is together with my business operation

    • @zheniachubarov3384
      @zheniachubarov3384 18 วันที่ผ่านมา

      @@MilanJovanovicTech thanks)

  • @mohammadryu
    @mohammadryu ปีที่แล้ว +1

    can you make a video about difference between input validation and business validation?

  • @shirazahmed5944
    @shirazahmed5944 ปีที่แล้ว +1

    From where did u learn all these concepts and what is your learning approach?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      A lot of searching the internet mostly, and trial and error

  • @camadan84
    @camadan84 10 หลายเดือนก่อน +1

    I am getting acompilation error on "ValidataionBehavior" class. Because TRequest must inherit from IRequest but you are inheriting it from ICommandBase and ICommandBase not inherits from IRequest. Am I right?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 หลายเดือนก่อน +1

      ICommandBase should be IRequest yeah

  • @wangshuo8619
    @wangshuo8619 ปีที่แล้ว +2

    Maybe we can do the validation in the middleware so that we don't need the pipeline behavior?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      But I can integration test the pipeline behavior easily, since it's all one request pipeline with MediatR. Showing that in a video in 2 weeks from today.

  • @Kylefuller002
    @Kylefuller002 9 หลายเดือนก่อน

    Should we validate the request coming into the ApiEndpoint before this validation? Do you need both?

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 หลายเดือนก่อน

      Depends, I prefer not to do it and just validate the command

    • @craigmunday3707
      @craigmunday3707 5 หลายเดือนก่อน

      I found a need to validate the request in the API layer because I prefer strongly typed primitives in the command classes. If I didn't do at least some early validation of the request then I was subjected to exceptions when the primitives didn't accept the data given to them.
      The application layer validates what couldn't be validated earlier, such as some conditional field logic, or rules that require data access.
      I took the view that each layer should be responsible for validating what it can?

  • @ildebertoV
    @ildebertoV ปีที่แล้ว +1

    well done,thanks

  • @mahyarazad
    @mahyarazad ปีที่แล้ว +1

    It's such pain to implement validation using Fluent! Why not using built in validation attribute, or even create a custom validation?

  • @alexmadnix
    @alexmadnix ปีที่แล้ว

    👍 Thanks for this video

  • @StileLiberoSud
    @StileLiberoSud ปีที่แล้ว +1

    Hello Milan, Thank you very much for this video. Can you give the source code of this video ? Thanks.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      It's available on Patreon, or just shoot me an email

    • @StileLiberoSud
      @StileLiberoSud ปีที่แล้ว

      @@MilanJovanovicTech I'm sorry, I did not understand.

  • @ivandrofly
    @ivandrofly ปีที่แล้ว +1

    4:00 record type with interface

  • @sunzhang-d9v
    @sunzhang-d9v ปีที่แล้ว +1

    Can RabbitMQ produce a video, the previous .net6 method does not seem to be supported

  • @nouchance
    @nouchance ปีที่แล้ว +1

    Первый на что я обратил внимание на то что шкафу стоит книга или диск с надписью "Warcraft".
    P.S Milan Old school gamer?)

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      I played a lot when I was a kid (maybe too much for my own good) 😅

  • @meowzhin
    @meowzhin ปีที่แล้ว +2

    Most of the people working with mediatr overcomplicate things with lots of unnecessary code. It saying is not useful, just saying I never seen useful code coming out of the “do this…” videos. The silver bullet concept is, honestly, ridiculous.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      How would you do it?

    • @meowzhin
      @meowzhin ปีที่แล้ว

      @@MilanJovanovicTech My man. Keep doing what you're doing because it's valuable for juniors and new comers.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      @@meowzhin It's valuable for anyone who wants to see the value

    • @meowzhin
      @meowzhin ปีที่แล้ว

      @@MilanJovanovicTech You want true feedback?
      You, and other people are part of the problem. The culture of "use this, do this" on which in the end is preference.
      It's really rare to find people who actually teach critical thinking instead of just "do as I say" creating a little cult, it's the same problem with MVPs.
      Every 6 months people change their minds and something new comes up and the ones who stay have to fix the inconsistencies and the huge pile of unorganized and unmanageable code.
      You're using the same titles and descriptions leaving important information conveniently left out.
      Every now and then a new religion is created and propagated by the same videos and medium posts. Same happened with Web Forms and MVC, then it was the DDD fever, clean architecture, now we are returning to monoliths with layers, my god.
      What you do IS valuable, don't get me wrong. I just think you (not you specifically, but creators in general) are purposely leaving important parts behind because you're either NEED it, to keep engagement or the MVP title, or just don't know. I'm pretty sure is not the latter.
      I'm not an IC anymore and I have to deal with a lot of juniors and mids who preach someone as their whole source of truth using the solution before asking what's the problem, a few hot topics now are kubernetes, clean architecture, ddd, mediatr (my god I hate this one), cqrs and a lot more, for example.
      It's the default in our industry to use preference as "the best way" of doing things and people follow it because they are learning new stuff, thus, hype driven development is created. It is and I was the same while learning with a friend who knew a lot more than I at the time, still does, to be fair.
      Micro services were the future!
      Not anymore I guess. Serverless... not!
      And I'm not saying refrain from using new stuff, far from that, I'm a big preacher of testing new things and learning through POCs in production, but that comes with a price that most people I've worked with over three continents, don't know.
      That's why you have to be careful with what you say and the way you say it. You're a influencer, you can't yell "FIRE!" and expect people not to panic.
      But I'm really tired of this discussion, it won't change anything and we have to keep pruning the hypers from solving issues they don't know with a solution they don't fully understand.
      I found you because someone used precisely this video as reference and guide. I came to check why, awesome content btw.
      Just remember you're in a position to influence people with a lot less knowledge than you and wording is important.
      You asked what I would do?
      First, tell me what do the customer wants, What's the problem we're trying to fix, Why,
      Then we can start talking technology and what's best for this particular project within the budget we have.
      I'm no criticizing you as a person but as an influencer.

  • @faisal3374
    @faisal3374 วันที่ผ่านมา

    Why you use minimal apis in every video?

  • @onedev7316
    @onedev7316 ปีที่แล้ว +3

    What about this one .... Domain Validation With .NET | Clean Architecture, DDD, .NET 6 th-cam.com/video/KgfzM0QWHrQ/w-d-xo.html which one is preferable?

    • @curtmantle7486
      @curtmantle7486 ปีที่แล้ว +1

      This is a question I often wonder about myself. There may be two phases of validation - one phase to validate the request to ensure it meets basic rules and another to validate the business logic, but it probably depends on the situation.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      There's input validation (this video) and business validation (the video you linked). I treat them differently.

    • @onedev7316
      @onedev7316 ปีที่แล้ว +1

      @@MilanJovanovicTech don't you think its bit too much if we have both validations?

  • @antonmartyniuk
    @antonmartyniuk ปีที่แล้ว

    I really like this approach. However in my projects I use FluentValidation for validating webapi requests, so you actually aren't writing any code for this as this is done out of the box. Fluent validation provides a middleware for webapi controllers. If you have minimal API - they you need to create your own middleware

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      Having validation in my MediatR pipeline means I can also test validation in my integration tests

    • @antonmartyniuk
      @antonmartyniuk ปีที่แล้ว

      @@MilanJovanovicTech I write integration tests that call my webapi and also test validation

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      @@antonmartyniuk Right, but you have to set up an HttpClient, get an auth token perhaps.
      My approach is just create a command/query and send it using ISender.

    • @antonmartyniuk
      @antonmartyniuk ปีที่แล้ว +1

      @@MilanJovanovicTech I use built-in WebApplicationFactory for such integration tests, so it's a minimal effort. I prefer this testing approach because I test the whole app or a microservice as it was deployed. If someone made a bug or change a version of the dependency that could crash the app on a startup or during webapi request execution. My tests will caught the issue and fail. That way my CI/CD will stop on this step and fail the build

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      @@antonmartyniuk I'm using the same approach, only one layer below. Testing the command/query pipeline 😂 So tests also go through startup, wire up all the dependencies, etc.

  • @techpc5453
    @techpc5453 ปีที่แล้ว +1