Thanks, Milan. I've noticed that some of our FluentValidation rules include checks that interact with the database, such as verifying unique names. While I understand the intent behind this approach, I believe FluentValidation is better suited for lightweight, in-memory validations (like required fields, lengths, and formats). Database-related validations, such as ensuring uniqueness, might be more appropriate in the service layer or enforced directly at the database level with constraints. This separation can help us maintain a clear separation of concerns, improve performance, and make our code easier to test and maintain. I'd love to discuss this further to ensure we're aligned and following best practices. Let me know your thoughts!
For unique checks you just inject a DbContext or DbContextFactory into the constructor, then set up a Must/MustAsync rule on the property, and a method that does the db check and returns boolean.
My intention is to not have such a case in fluent validation. It should be at the application I level. If you need to check for uniqueness and show it in ui then maybe create a specific endpoint.
What's the main drawback for me personally when using fluent validation is that I can not step into the validation method and see what data is being checked, also I can not write tests to validate "null" inputs as fluent validation expects some type in order to validate against it. Any solutions there?
I want to know, too. To me, all classes should be immutable or well encapsulated. And if your concern is JSON serialization, that's still possible with constructor and getters.
@@faheemmalik1810 I left a comment. How we do it is first validate input basic validation and if that passes we validate business logic (lets say you need to call external api to validate) so kinda 2 layer validation, first being "fail fast and cheap".
Milan, great vid as always! Quick question, if you have basic input validation (field length, nullability, etc.) and some external validation (call other apis, to validate data, let's say that id exists in some other part of the system) would you do it in one validation scenario or split to 2 for "fail fast" so that user would first fix basin input errors, and then we would make expensive calls to do validation against external integrations of the system? Second option does make sense right?
Great vid, if we're chaining validation, or wrapping validators into group validators, would multiple validator calls in one "god method" be more readable, or should we apply chain of responsibility pattern here?
Not sure if it's sad or not, but we write our own validator classes instead of using Fluent validation because of performance. Yes, the syntax is less functional :) But I still feel like Fluent validation _is_ the right way.
@@ZubriQue I think you're better of without fluent validation. You have more power the way you do it. The declarative style of fluent validation is a weakness imo.
its ok for fast development and basic things, plus you can also do custom validation with it but in the long run when things get big its harder to maintain as it ruins SRP. fluent api is way better imo.
btw, as I noticed minimal apis are used in the video. they do not have built-in validation APIs like controllers do, so to use data annotation you gotta install MinimalApis.Extensions nuget package and put WithParameterValidation() filter.
@@adelekeademolu if you use dtos, that's the main purpose for it. the contract how you speak to the outside of your api, and yes, you need to map your dto to your internal model or entity to do other operations, with that, I do not see the point or getting things corrupted.
@MilanJovanovicTech They are dragged into many projects that I work on. I don't always have a say. I've not contributed much at all, and what I have contributed is not much appreciated! 😅 That doesn't make fluent validation any better though! I think validation of input (that is mostly made up of primitive values) should output strongly typed value objects. I've made my own system for this, but of course, only I myself is using it. :)
Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
A very good tutorial Milan, a topic every programmer needs to know - plus it's a cleaner approach
Thanks!
Thanks, Milan. I've noticed that some of our FluentValidation rules include checks that interact with the database, such as verifying unique names. While I understand the intent behind this approach, I believe FluentValidation is better suited for lightweight, in-memory validations (like required fields, lengths, and formats).
Database-related validations, such as ensuring uniqueness, might be more appropriate in the service layer or enforced directly at the database level with constraints. This separation can help us maintain a clear separation of concerns, improve performance, and make our code easier to test and maintain.
I'd love to discuss this further to ensure we're aligned and following best practices. Let me know your thoughts!
For unique checks you just inject a DbContext or DbContextFactory into the constructor, then set up a Must/MustAsync rule on the property, and a method that does the db check and returns boolean.
My intention is to not have such a case in fluent validation. It should be at the application I level. If you need to check for uniqueness and show it in ui then maybe create a specific endpoint.
Uniqueness is best handled with a unique constraint/index. As I said in the video, I wouldn't do this in the validator.
@@MilanJovanovicTech yeah it is true
What's the main drawback for me personally when using fluent validation is that I can not step into the validation method and see what data is being checked, also I can not write tests to validate "null" inputs as fluent validation expects some type in order to validate against it. Any solutions there?
You could use ASPNET here to guard you against null values, since it can't bind it to a non-null type.
Hi one question regarding the DTOs , Why we using setter in all properties in DTOs ?
I want to know, too. To me, all classes should be immutable or well encapsulated. And if your concern is JSON serialization, that's still possible with constructor and getters.
Nothing is changing it, didn't want to concern myself with that. We could do get/init
Great video, Thanks!
Some examples of Business Validations and where to put them will be much appreciated.
@@faheemmalik1810 I left a comment. How we do it is first validate input basic validation and if that passes we validate business logic (lets say you need to call external api to validate) so kinda 2 layer validation, first being "fail fast and cheap".
Do it in the use case directly
Milan, great vid as always! Quick question, if you have basic input validation (field length, nullability, etc.) and some external validation (call other apis, to validate data, let's say that id exists in some other part of the system) would you do it in one validation scenario or split to 2 for "fail fast" so that user would first fix basin input errors, and then we would make expensive calls to do validation against external integrations of the system? Second option does make sense right?
I mentioned that I prefer having third-party calls in the use case (controller/service/MediatR handler) because it's easier to deal with failures
Thank you great tutorial!!!
Do you have any recommendations on best practices on how to apply automatic auto validations?
I think that's been deprecated
Great vid, if we're chaining validation, or wrapping validators into group validators, would multiple validator calls in one "god method" be more readable, or should we apply chain of responsibility pattern here?
Where would we use this "god method"?
Milan, could you please use Controller in your examples? I feel like everything in 1 file Program.cs makes codes more brain tiring to read.
Maybe 🤔
Thanks bro, your tutorials are extremely helpful for us newbs :)
Thanks!
Show how to validate enumeration passed into the api. Fighting against the json deserializer makes the solution I found not clean
Will do, in a future video
@@matthewhartz9235 if Microsoft didn't conflate deserializing with mapping the data into a typed object, maybe you'd be fine?
I have used fluent with mediator in my project 7 years before
What about now?
@@mr-black_rock321 cool...
Really good video, I like how you explained all of these features as well as your demo. Thanks!
You're welcome!
Not sure if it's sad or not, but we write our own validator classes instead of using Fluent validation because of performance.
Yes, the syntax is less functional :)
But I still feel like Fluent validation _is_ the right way.
@@ZubriQue I think you're better of without fluent validation. You have more power the way you do it. The declarative style of fluent validation is a weakness imo.
Great video for most common apis
Thanks!
A very good detailed tutorial
Thanks!
Why not just use data annotstions ?
Maybe so that you models don't get corrupt
its ok for fast development and basic things, plus you can also do custom validation with it but in the long run when things get big its harder to maintain as it ruins SRP. fluent api is way better imo.
btw, as I noticed minimal apis are used in the video. they do not have built-in validation APIs like controllers do, so to use data annotation you gotta install MinimalApis.Extensions nuget package and put WithParameterValidation() filter.
bad
@@adelekeademolu if you use dtos, that's the main purpose for it. the contract how you speak to the outside of your api, and yes, you need to map your dto to your internal model or entity to do other operations, with that, I do not see the point or getting things corrupted.
I think fluent validation and mediator are the two worst contributions to the .net ecosystem.
You're free not to use them. What have you contributed to the .NET ecosystem?
@MilanJovanovicTech They are dragged into many projects that I work on. I don't always have a say.
I've not contributed much at all, and what I have contributed is not much appreciated! 😅 That doesn't make fluent validation any better though! I think validation of input (that is mostly made up of primitive values) should output strongly typed value objects. I've made my own system for this, but of course, only I myself is using it. :)