Make Your Business Rules Cleaner With Fluent Validation

Sdílet
Vložit
  • čas přidán 7. 09. 2024

Komentáře • 93

  • @MilanJovanovicTech
    @MilanJovanovicTech  Před rokem +4

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

  • @djoka4203
    @djoka4203 Před rokem +3

    Even if i won't watch it immediately I must enter, just to smash that like button for our good friend Milan. Hvala ti brate!

  • @GiovanniCostagliola
    @GiovanniCostagliola Před rokem +5

    Hi Milan, thanks for sharing.
    My two cents: Command validation pertain to the Behavioural layer of the application and should be costrained to that layer.
    Assumed your stack, the best and elegant approach is to implement an CommandValidationBehaviour into the Mediatr pipeline.
    This middleware would throw a CommandValidationException that can be further processed by the upstream layers, presentation in particular.
    MOREOVER, and this is the point, you can also (and SHOULD) implement a (synchronous and "singletoned") validation at Request layer.
    This latter validation layer is to guard from malformed user request (aka 404): stateless, light, focused on syntax rather then semantics, and very performant (the "why" of singleton).
    while the former, is to protect from business violation rules (aka 401, 400 and so on…): deeper and semanthics reach.
    A bit of duplication may arise but in complex application, where you reuse commands in multiple use cases, this design is very scalable.
    The point to recognize is that validation is a topic that you should address at every layer of your onion…
    Thanks for your time

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      I agree, and I already have a video about implementing the Validation pipeline behavior.
      How would the request validation be implemented? What's your approach?

  • @m5s10
    @m5s10 Před rokem +1

    I was just about to write that you should index database calls that you use in validator, but then you showed the ef configuraiton. Nice work :)

  • @fredericmerouze4876
    @fredericmerouze4876 Před rokem +3

    great video milan ! for my projects, i use the pipeline behavior with mediatr to doesn't have redundancy in my handle method :).

  • @Andy01010
    @Andy01010 Před rokem +3

    Would be nice to have these rules in the domain layer, to really encapsulate the domain logic where it belongs

  • @gianlucalocri
    @gianlucalocri Před rokem +4

    I know... I am pedantic, but I am trying to understand and your videos are a gold mine. That said, why put the validation in the application layer? It seems that email uniqueness is a business rule, so validation must occur in the domain layer. Am i missing something?
    Thanks for your patience Milan.

    • @_JustBeingCasual
      @_JustBeingCasual Před rokem

      I think in the Persistance 'CustomerConfiguration' he already assigned it to be unique, so duplicates can never happen; to be honest I don't like the idea of giving the model on creation a repository and then do a 'check', if it already exists (from performance perspective also), but I did like the idea to enforce everything.
      I don't think a repository belongs in a model, anyways because there are probably ways to get DI working in there.

    • @pilotboba
      @pilotboba Před rokem +1

      So you want to inject persistence into your domain layer?
      If not, how would you enforce this in the domain?
      Not sure I like those dragons.

    • @gianlucalocri
      @gianlucalocri Před rokem

      @@pilotboba I hope the above comment will not be banned for containing two links. If it is so, please tell me so I can provide information about where to find the resources without providing the direct URL.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem +1

      It's the everlasting debate of domain purity vs completeness vs performance
      You can't have all three.

  • @bbualdo
    @bbualdo Před 3 měsíci

    You are just like MS Docs. Assuming that everyone is an expert already and just writing code without explaination.

  • @dragannikolic568
    @dragannikolic568 Před rokem +1

    Its very helpful to follow your videos. I see here many are bugging you with wanting some ideal code in the video. I see that I can build application together with you and learn and improve knowledge. So once again, great and very helpful approach in videos content, the plan on what you publish with compromise and refactoring in later videos. Thx. a lot. And by the way you have call to repo by passing email where name should be passed in comand handler class. Just wanted to brag that I'm closely watching and implementing your examples 😉

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem +2

      It's funny how everyone expects me to implement a complete production ready application in a 10-min video, and I only want to focus on something specific while disregarding everything else. As long as people like you can see the value, that's all I care about.
      Yeah, the double Email in the constructor pissed me off but I didn't want to re-record to fix it 😅

    • @dragannikolic568
      @dragannikolic568 Před rokem

      @@MilanJovanovicTech We wouldn't be able to learn and apply new knowledge if you put all at once by omitting showing parts of the code and cutting explanations. Gradual approach is the only way for us who do not know everything already, or we just don't need to play smart. I use to watch your video one day, then implement it myself next day by checking the video while developing. This works for me. I suppose this is why you get so many new followers.
      First thing that I thought was the same. He must be crazy about rerecording that trivial typo 😁 Wish you all the best!

  • @christianmorales3496
    @christianmorales3496 Před rokem +4

    should we use fluentvalidation for the domain layer? in this case it is used as an "application rule" right? How do we differentiate business rules and application rules?

    • @efimov90
      @efimov90 Před rokem +1

      Very good question, but shouldn't domain layer be referencesless?

    • @moviedomof
      @moviedomof Před rokem

      Buena sugerencia : Seria los mismo que una API comun de streeming Task UploadFile() con var file = Request.Form.Files[0];. Luego Internamente en la capa de Infra un FTPWrapper que lo envie al FTP server. (Obtions-> previouslyconfigurated. not harcoded ajjaja )

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      Application is also part of the Core (where Domain also is) so it's one and the same

  • @CodeWithAnup
    @CodeWithAnup Před rokem +2

    how to export the metadata of entity validation rules into Json for front end.
    The problem I am trying to solve here, when our client side is SPA (Angular/React) we have to write same validation logic twice in back end and also in front end.
    I wan't to create a unified validation both back end & front end. So that I only write validation rules once.
    For example I wan't to export rules in following format :
    {
    "Name": {
    "NotEmpty": true,
    "MinLength": 3,
    "MaxLength": 200
    }
    ...
    ....
    }

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      I don't see much value in that... You'll write it twice (once...) and forget about it

  • @javiermayorga9857
    @javiermayorga9857 Před 11 měsíci +1

    Hi Milan, thanks for your amazing videos I learn a lot from them. I do have a question regarding of how Can keep my service class clean and elegant when I need to implement more than 1 validators in the constructor?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před 11 měsíci

      You can inject IEnumerable and validate all of them - but at that point you're better off using some sort of middleware

  • @orange_cat_energy
    @orange_cat_energy Před 6 měsíci +1

    CreateCommand validations are almost the same for UpdateCommand validations, how to handle that?

  • @29Aios
    @29Aios Před rokem +2

    И вообще, что это за подход - проверять уникальность email перед вставкой юзера ? Нужно иметь уникальный ключ в БД по email, попробовать вставить в транзакции, и затем добавлять юзера, а если такой email уже есть, то все откатить - хотя email просто частный случай, а более общий - валидация на уровне БД, вставляем, не получается по уникальному индексу, откатываем что сделали до этого. Т.е. в нагруженных системах, между проверкой уникальности и вставкой проходит время, хоть и миллисекунды, но это надо учитывать - и единственный вариант, индекс, транзакции - это если еще что-то связанное вставляем.

    • @Maxim.Shiryaev
      @Maxim.Shiryaev Před rokem +1

      Или блокировка всей таблицы с момента чтения до момента записи нового email. Что в высоконагруженной системе невозможно.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      Pessimistic vs optimistic approach

    • @29Aios
      @29Aios Před rokem

      @@MilanJovanovicTech Верно. Но сам подход должен быть пессимистичным, и все должно быть решено на уровне БД, а не клиента БД.
      С email, оптимистичный подход может сработать, и за 10 лет никогда в такую ошибку можно не попасть, даже в высоконагруженных системах, но в других случаях это невалидно, и если уж взялись учить, то учите правильно.

  • @Paul-uo9sv
    @Paul-uo9sv Před 9 měsíci

    thanks buddy. Good stuff right here.

  • @hemantpanchal8087
    @hemantpanchal8087 Před 4 měsíci

    How to pass multilingual message in fluent validation without .resx approach. I have list of language specific error messages stored in database.

  • @MahmoudSaed98
    @MahmoudSaed98 Před 4 měsíci +1

    why Add Customer Method Not Async ?

  • @gonzalorf
    @gonzalorf Před rokem +3

    How do you handle concurrency? Is it possible to receive two requests using the same email at the same time without being aware of the other attempt to save a customer with that email?

    • @gonzalorf
      @gonzalorf Před rokem +1

      I didn't see the part where you set an index. Thank you.

    • @29Aios
      @29Aios Před rokem

      @@gonzalorf Sure, there should be used another approach - insert email into a table with unique email column index, and also insert customer/user in one transaction.

    • @Maxim.Shiryaev
      @Maxim.Shiryaev Před rokem +1

      The idea to check uniqueness before an attempt to store new email into the database is dangerous. Either you should lock entire table on reading or you should catch a key violation exception on writing.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      Unique constraint at the DB

    • @29Aios
      @29Aios Před rokem

      Then you do not need to check if an email exists, just insert it, and catch key violation, first call is not needed.

  • @abdelrahmananwar885
    @abdelrahmananwar885 Před 7 měsíci

    keep up the great content

  • @Zisane21
    @Zisane21 Před 5 měsíci

    How would you convert Fluent Validation errors to ProblemDetails object?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před 5 měsíci +1

      This + a global exception handler: www.milanjovanovic.tech/blog/cqrs-validation-with-mediatr-pipeline-and-fluentvalidation

  • @I_Am_Dani
    @I_Am_Dani Před rokem +2

    Can u Teach File Uploader Service With Ftp Type in Cqrs pattern ?

  • @_JustBeingCasual
    @_JustBeingCasual Před rokem +3

    Can't you add the command validator to the createcustomercommandhandler instead of the controller/route? That it stays together and will be explicit? That can either be together in that file or as DI.
    Thanks for the video :-)

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem +1

      Commands don't return a value, so didn't want to bother with implementing a flow for that. It was easier to just place it in the endpoint to illustrate the point

  • @efimov90
    @efimov90 Před rokem +1

    Isn't it breaking dependency indirection? I mean you define concrete implementation of validation right in application layer. Or is it a compromise?

  • @emmanuelpolancojimenez7807

    Why do you not use a Pipeline Behavior to add a validation layer before the handler. I think that with that the handler will be much cleaner

    • @pilotboba
      @pilotboba Před rokem

      HE commented about that at the very end of the video.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem +1

      Just an example + I already have a video about that

  • @degrauxmaxence8871
    @degrauxmaxence8871 Před rokem +1

    What the benefit of validate the command in the API rather than in the handler ?
    If we use the same handler in 2 differents route, we'll duplicate the code ? (maybe too specific case ?)
    Anyway, thanks for sharing this !

  • @imaneldegwy1478
    @imaneldegwy1478 Před 10 měsíci +1

    how can we validate with more than one parameter?
    can u show me sample code for that

  • @SuperLabreu
    @SuperLabreu Před rokem +1

    Hi,
    Just curious on how you guys use these db checks without hints that try to lock the table...for instance, with the default transaction level for sql server, how can you ensure that 2 parallel requests won't end up duplicating the records with the same email?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem +1

      There's a unique index on the DB level, only one of them can insert the record

    • @SuperLabreu
      @SuperLabreu Před rokem +1

      @@MilanJovanovicTech if that is the case, what's the purpose of the db check in code?
      It's just slowing down your app, no?

  • @29Aios
    @29Aios Před rokem +1

    Да ну нафиг, как-то сложно для простой валидации.
    ЗЫ. Работал на одном проекте, и там то-же все было сделано на командах/запросах, причем еще и в генериках, ужас - чтобы разобраться в коде, приходилось искать имплементацию за 3 шага, место одного, а там таких было тысячи. В итоге проект пришлось спасть, т.к. при разрастании он стал неподдерживаемым (not-maintainable). Есть-же принцип KISS - ну зачем усложнять на ровном месте ???

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      Just an example of using async validation with FluentValidation, doesn't have to be how you do it

    • @29Aios
      @29Aios Před rokem

      @@MilanJovanovicTech Понятно, что это пример как можно сделать проекту плохо - завести кучу всяких интерфейсов, абстракций, которая в будущем, казалось бы, может что-то принести, а по факту все очень усложняет - разработчики вынуждены исследовать код, скакать по реализациям интерфейсов и т.д. Хотя, чего проще, просто проверить email в сервисе юзеров при его добавлении ? KISS - Keep it simple s****d

  • @gabrielordonez7876
    @gabrielordonez7876 Před rokem +1

    Hi Milan, I would like to know what is the theme you use in Visual Studio and if you plan to publish a course in the future?

  • @algsavi
    @algsavi Před 3 měsíci

    If its a business rule, why isn't it on domain layer?

  • @CRBarchager
    @CRBarchager Před rokem

    12:30 What extension/setttings do you use to show all the current values to the right of your code?

  • @saulolima6874
    @saulolima6874 Před rokem +1

    Thx

  • @synthaistudio
    @synthaistudio Před rokem +1

    Yoo Milan! It's either you're too fast or I'm too slow "compiling" what you are writing there. Adjust your mediator brooo, allow the stupid me to catch up 😢

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      Yeah, I kind of assume people have some idea of what I'm talking about. I'm not really "beginner" friendly

  • @gp390
    @gp390 Před rokem +1

    Are you from Croatia? 🙂

  • @mustafahaider9115
    @mustafahaider9115 Před 6 měsíci +1

    man I am new to the channel and every time I watch a video I feel like a stupid potato cuz u r always using things u already built and I just don't know where to start like what is the Error class what is a pipeline behavior I feel so lost.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před 6 měsíci

      Here's the Result class: gist.github.com/m-jovanovic/aa25b1ae424c985ff8ae696a79b6fe6e
      But try to focus on the concepts, the implementation details can change

  • @harrisonwell1719
    @harrisonwell1719 Před rokem +1

    You explain things way too fast and jumping from on one thing to another, I would like you to slow down a bit and explain things properly

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před rokem

      I generally expect viewers to be somewhat familiar with the topics. Unless it's a beginner video - and this one isn't

    • @harrisonwell1719
      @harrisonwell1719 Před rokem

      @@MilanJovanovicTech fair enough

  • @techpc5453
    @techpc5453 Před rokem +1