Validation Behavior | MediatR + FluentValidation | CLEAN ARCHITECTURE & DDD Tutorial | Part 8

  Рет қаралды 41,687

Amichai Mantinband

Amichai Mantinband

Күн бұрын

Пікірлер: 97
@tiagohenrique7685
@tiagohenrique7685 Жыл бұрын
Hi Amichai! Greetings from Brazil! I am so grateful for your series! I've been following this far and everything just gets better!! Congratulations! Content like this is very rare!
@gabriel.pessoa
@gabriel.pessoa 7 ай бұрын
Brazillian here too! Amichai is helping me so much at my first dev job
@ugochukwuumerie6378
@ugochukwuumerie6378 2 жыл бұрын
Great content 👌 especially the ending part - Yes!. The pipeline behaviours are like class decorators which obeys the "O" in the SOLID principles - the class should be closed for modifications and open for extensions.
@liordagan5098
@liordagan5098 2 жыл бұрын
What?! Zero comments about the most beautiful part of this video?! 😍🐶 28:15
@amantinband
@amantinband 2 жыл бұрын
Same!
@patrykk.4630
@patrykk.4630 2 жыл бұрын
Thanks for this video. I was waiting for a good explanation of MediatR behaviors and validating. Can't wait for domain and application validaiton breakthrough :D
@being_aslam_tiger
@being_aslam_tiger 2 жыл бұрын
Thanks for creating awesome stuff. Please keep making videos on c#.
@amantinband
@amantinband 2 жыл бұрын
Thanks, Aslam!
@davidpccode
@davidpccode Жыл бұрын
Hello great content. Thank you very much. I have read and seen a lot of content about command validation but I still can't find a reason that justifies so much over-engineering and so much complexity. I can achieve the same thing by injecting a class that performs all the validations with less than half the effort and with the same result. what am i missing? Thanks in advance 👍
@pilotboba
@pilotboba 2 жыл бұрын
So let's go back to when I asked you why your Commands/Queries weren't your API contracts. You stated that you wanted to be able to change the commands/queries implementations without changing the contracts. Ok, fair enough. However, now, you are validating the Command and not the request. So, when you return a validation problem it is possible you are defining a validation problem on a property that doesn't actually exist on the contract. So, your RegisterRequest could have FullName which you map to First Name, Last Name in your command. Your validator finds the Last Name is empty and returns a problem that states, LastName is required or some such error. How is the client supposed to fix this, because he has no LastName property in his contract? Am, I seeing this correctly, or did I miss something?
@amantinband
@amantinband 2 жыл бұрын
Great question. You are correct; since we are validating the executing command/query and not the actual request, there can be a mismatch between the two. One of the cons of Application-layer validation (instead of presentation-layer validation) is that we might have already moved from the API request model to the use-case model, and there might be a mismatch. One of the benefits of application layer validation is that you can take into account application logic and include it in your "Bad Request" response. Is it a big deal that the property name in the response's error list doesn't match the request property? I would argue that it usually isn't, but as always, it depends. What do you think?
@pilotboba
@pilotboba 2 жыл бұрын
@@amantinband I think as a client interacting with an API if I got an error message about a property that wasn't in the request I wouldn't know what to do to fix it or create client-side validations that match the contract. So, in my opinion the Commands and Queries should BE the API contracts. If you need to modify command isn't it a different command, and you should add a new one and maybe deprecate the old one.
@amantinband
@amantinband 2 жыл бұрын
On a specific project, maybe. But as a rule of thumb, I would disagree. The API should be known and well documented, and the error response should be descriptive. These together should cover the client’s onboarding to the service. The commands/queries aren't always a 1:1 mapping, and having this abstraction is what the presentation layer is all about. Finished modeling your service and want to switch to gRPC? No problem, you would only update the presentation layer. At Microsoft, there are some services where you have the same flows available for some clients via a REST API and other clients via another technology style bond or gRPC. What do you think? Was that convincing?
@pilotboba
@pilotboba 2 жыл бұрын
@@amantinband No. I think we are agree about 1 thing, the contracts shouldn't change, but disagree that they should be, or need to be different than the commands and queries. Adding another layer and seem that I don't feel is needed. I guess if you document your error responses it's not too much of an issue, but it just doesn't sit right with me.
@ugursesen7629
@ugursesen7629 2 жыл бұрын
the tutorials are really great, thanks a lot
@amantinband
@amantinband 2 жыл бұрын
Thanks, Ugur!
@Jeroen3001
@Jeroen3001 Жыл бұрын
Instead of invoking a Dynamic Call Site by using the 'dynamic' keyword in '(dynamic)errors' (which is slow) the same effect is accomplished by a simple cast from an object reference: '(TResponse)(object)errors' I try to prevent to use the keyword 'dynamic' at all times when possible.
@m_camper
@m_camper Жыл бұрын
Hi, I'm thinking the same thing and was just about to post a new comment asking if I can do this, but I see I'm not the only one who thinks so 🙂
@m_camper
@m_camper Жыл бұрын
But actually, why another approach is with using reflection but not that simple as in your comment, may be there are some reasons that it will not work?..
@ariefmuhammadlubis1803
@ariefmuhammadlubis1803 2 жыл бұрын
Finally, I'm very happy and great video
@KarwanEssmat
@KarwanEssmat Жыл бұрын
Well Done Amichai, I am excited to fo find your course. it is truly helpful. Actually, I did not use your Error0r library so I had some challenges in returning the exception errors and I used my approach. Thanks for sharing.
@StandleyPeter
@StandleyPeter Жыл бұрын
I really enjoy the series. Have learned a lot from these series. Anyway, alt+z should toggle the words wrap automatically.
@fakeITDevTeam
@fakeITDevTeam Жыл бұрын
i wish i could be as good as you guys in software development world.
@minhan4444
@minhan4444 6 ай бұрын
Thank you very much about this tutorial :3
@sunnypatel1045
@sunnypatel1045 2 жыл бұрын
Hey dude love your content. Are you going to do a video on testing the api? Love to see your strategy etc.
@amantinband
@amantinband Жыл бұрын
Yup 👍
@arthurfedotiew3609
@arthurfedotiew3609 Жыл бұрын
i don't know if it's just me but that final part with pipeline and Aggregate was so much easier for me when I learned this concept a while ago in js world working with rxjs .pipe(). YOu should probably rename 'pipeline' to 'behavior' when defining Aggregate reducer. Nevertheless, content is terrific as always, thank you Sir!
@TrOgaN_
@TrOgaN_ 3 ай бұрын
I noticed someting strange, while the validation handler is called, validation errors are returned before it calls the handler. You can even comment out the pipeline definition in the dependency Injection file and it still return validation erroros.
@sunnypatel1045
@sunnypatel1045 2 жыл бұрын
Love your content. It's SO CLEAN :D. Will you demonstrate other behaviors like logging etc?
@amantinband
@amantinband 2 жыл бұрын
I might be. Unsure if it would be the simplest way to demonstrate logging, though.
@mahditalebi1770
@mahditalebi1770 2 жыл бұрын
Thanks for the video. It's a little bit hard to read without word wrapping and big font. if you could maybe close the files list or decrease font a little I think it would be much easier to undrestand.
@amantinband
@amantinband 2 жыл бұрын
Ooh, interesting feedback. It would be easier for me to code with a smaller font. Do you watch the videos on your phone or computer?
@mahditalebi1770
@mahditalebi1770 2 жыл бұрын
@@amantinband I watch them on my laptop which is 15'.
@nivaldobrasil
@nivaldobrasil Жыл бұрын
Thank you.
@novalogic1265
@novalogic1265 2 жыл бұрын
Great video as usual. Just one thing, instead dynamic I've implemented in this way: First, I split Command and Query into 2 interfaces public interface ICommand : IRequest { } public class ValidationBehaviour : IPipelineBehavior where TRequest : ICommand { private readonly IEnumerable _validators; public ValidationBehaviour(IEnumerable validators) { _validators = validators; } public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) { if (!_validators.Any()) { return await next(); } var context = new ValidationContext(request); var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))); var errors = validationResults.SelectMany(result => result.ToErrors()).ToList(); if (!errors.Any()) { return await next(); } return errors; } } Because, if I need ErrorOr in e.g. some behavior (logging or whatever) after next() to log something with this approach I have an ErrorOr object. What do you think? Also, I dont like dynamic and I dont like exceptions 😉 Edit: result.ToErrors() line ToErrors is an extension😀
@amantinband
@amantinband 2 жыл бұрын
And the behavior is invoked? I'll have to check this out if yes
@novalogic1265
@novalogic1265 2 жыл бұрын
@@amantinband Yes, behavior is invoked. Here is my request example public class RegisterCommand : ICommand .... So ApiIdentity is TResponse
@amantinband
@amantinband 2 жыл бұрын
@NovaLogic Can you hit a breakpoint in the behavior? If yes, will you be able to share a gist? AFAIK this isn't supported yet.
@novalogic1265
@novalogic1265 2 жыл бұрын
@@amantinband drive.google.com/drive/folders/1K3-OQBcpEZdufXjukj14xEXJ_2LWvcW-?usp=sharing let me know if you have an access issue
@SzefMann
@SzefMann 2 жыл бұрын
Great content! What kind of programming books do you recommend?
@amantinband
@amantinband 2 жыл бұрын
I rarely read books. Mostly learn from documentation, blogs, and my favorite - existing code bases.
@SzefMann
@SzefMann 2 жыл бұрын
@@amantinband Pls give examples of existing code bases :D
@amantinband
@amantinband 2 жыл бұрын
I spend a lot of time searching within Microsoft's internal code bases. These are the best models of how services (and microservices) scale. Some technologies and architectures also have great examples and templates available on GitHub
@zadidbinazad3655
@zadidbinazad3655 Жыл бұрын
I have just started to move my API to clean architecture. This helps a lot. Thank you. ❤ Can we have some details about how to work with a SQL database following your approach and how to run CRUD operation in Database?
@SirSpiffzz
@SirSpiffzz 2 жыл бұрын
Love your videos!
@dennisdurairaj3848
@dennisdurairaj3848 2 жыл бұрын
Hey Amichai, great content! I've got a question. Doesn't this go against DDD principle of keeping logic(validation in this case) inside entity classes and ValueObjects in the domain? Right now the domain has no knowledge of these validations
@abrahamv09
@abrahamv09 2 жыл бұрын
I understand that some validations are going to be repeated in both places, but they are more like insurance. I see it as a way to avoid executing logic that will be invalid due to input parameters. Not all requests will reach the domain layer if you validate the parameters before performing an operation with that layer. Other cases will not even have interaction with the domain, but you will still have to validate input parameters, such as queries. After that, if you somehow make your parameters invalid after the command validators, domain validation will be your insurance. That's how I understand it. Although there are cases where you can ignore the command validators and just use the domain validation, it is up to you.
@msek97
@msek97 2 жыл бұрын
Will you cover unit testing of the handlers? I’m curious how do you test it with so implicit validation that is sctually done in runtime behind the scenes. Should we not test invalid inputs then?
@amantinband
@amantinband 2 жыл бұрын
Hey Sekresio. Yes, we'll have a couple of videos on testing 👍🏼
@matthewrossee
@matthewrossee 10 ай бұрын
What status code would you assign to Error.Failure? 500? I guess it depends on what I understand by a failure in my system. I think that NotFound, Conflict and Validation solve the 99% of the usecases. So the Failure could mean some unrecoverable error caused by the server, but the one that you expect to happen eventually. But then what about Unexpected? If you ever return Error.Unexpected in your code, it means that you expect something may happen, so it isn’t unexpected. What is your methodology? And big thanks for the amazing erroror library!
@marioteik
@marioteik 2 жыл бұрын
I love your content!
@amantinband
@amantinband 2 жыл бұрын
Added now, thanks for noticing!
@baulron
@baulron 6 ай бұрын
Thanks!
@amantinband
@amantinband 6 ай бұрын
🫶🏼
@alexc.5781
@alexc.5781 Жыл бұрын
All my sympathies to your enter key
@robertmrobo8954
@robertmrobo8954 Жыл бұрын
Do you have an issue with the 'J' button on your keyboard Ami? 😊 Very very very very good videos by the way.
@ayazsohail652
@ayazsohail652 Ай бұрын
I changed the validateBehavior from register command to generic type, now validation is not working, API gives no error response.
@gungoromer
@gungoromer Жыл бұрын
Teşekkürler.
@amantinband
@amantinband Жыл бұрын
Thanks! 🫶🏼
@androidsavior
@androidsavior 5 ай бұрын
Can you share the source code of this project ?
@harmony-teams
@harmony-teams 2 жыл бұрын
Great video! Do you use some type of VS Code extension that proposes the code to complete the statement?
@geraldmaale
@geraldmaale Жыл бұрын
GitHub Copilot
@juankar008
@juankar008 5 ай бұрын
github copilot
@foonlam7134
@foonlam7134 7 ай бұрын
I am very confused. Why do we need pipeline behaviors? A pipeline behaviour basically does something before the the request is handled and after the request is handled. Why can't we make it just part of the request handler? If it is to implement single responsibility, then why can't we just just call one handler after another in order which does the same thing as the pipeline.
@KLGR125
@KLGR125 6 ай бұрын
Thats because you want to separate use case handlers from validation. If I understand you correctly, if you create multiple handlers in mediator for every validation you will end up having long chain of mediator invokes in your controller and this chain gonna increase every time you need to add new validation rule. Or you can add your own validator somewhere and invoke it from command handler and this will be single responsibility principle violation. So you want your validation separated both: from command handler and from controller and this what pipeline behavior allows you to do.
@ahmetcanyldz7455
@ahmetcanyldz7455 Жыл бұрын
Is it more sensible to configure the life cycle of the fluent validation objets singleton rather than scoped?
@arthurfedotiew3609
@arthurfedotiew3609 Жыл бұрын
Shouldn't you assign null to IValidator? validator at 12.36 when injecting optional validator?
@bookuha
@bookuha Жыл бұрын
Do these commands act like a DTO? Is it appropriate? Should I pass DTO's into them and validate them like that? Doesn't look right for me :c
@mohamedyounesse
@mohamedyounesse Жыл бұрын
Can use it in wpf pip behaviors mediatr i thing is distinated for web only asp because i try it many time i given error the services logger cant injected with wpf there are no request
@kennedydre8074
@kennedydre8074 8 ай бұрын
anyone know how we are connecting the debugger?
@eugene_potashkin
@eugene_potashkin 2 жыл бұрын
Finally 😃
@omidkianifar5144
@omidkianifar5144 2 жыл бұрын
Thanks for the course. Why u didnt validation on api layer on request models?
@amantinband
@amantinband Жыл бұрын
That's another common approach. I like putting the validation in the application layer rather than the presentation layer.
@omidkianifar5144
@omidkianifar5144 Жыл бұрын
@@amantinband this is for performance. In this case what do u prefered? Performance or clean code
@muhammadahsansaifi5182
@muhammadahsansaifi5182 Жыл бұрын
Oh my God
@vuphancao1224
@vuphancao1224 Жыл бұрын
what is the name extention suggest code in visual code you use ?
@DaminGamerMC
@DaminGamerMC 2 жыл бұрын
Why the "is 0" thing works
@DeejayWazzouille
@DeejayWazzouille 2 жыл бұрын
Hello, I dont understand the need of this behaviour ? I dont have it and my code still returning the errors as your
@DeejayWazzouille
@DeejayWazzouille 2 жыл бұрын
Nevermind, it's because you validate the command when i validate the request .. :)
@pilotboba
@pilotboba 2 жыл бұрын
small FYI, this part isn't in the play list. :)
@amantinband
@amantinband 2 жыл бұрын
Thanks, added now!
@rmbl349
@rmbl349 2 жыл бұрын
I love your content but it's really strange for me that you use vs code for this. To be honest without VS + resharper or Rider I feel really unconfortable.
@amantinband
@amantinband 2 жыл бұрын
Each one with its pros and cons 🙂
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Fix the thumbnail! 😁
@amantinband
@amantinband 2 жыл бұрын
Whoops pipline 😂 Thanks 🫶
@MyFuzzyAfterlife
@MyFuzzyAfterlife 2 жыл бұрын
Just some feedback, and this may just be applicable to me. But you go very fast, it's sometimes hard to keep up, and Co-Pilot is not helping with this either. I'm constantly pausing, rewinding, pausing, just to try and keep up. Maybe I'm just slow.
@amantinband
@amantinband 2 жыл бұрын
Whoo thats great feedback. I tried going a bit slower in this vodeo, so I'm very curios to hear if others feel the same specifically regarding todays video. Thanks for letting me know!
@ryan-heath
@ryan-heath 2 жыл бұрын
I viewed the vid at 1.5 speed 😅 But then again I’m not particular interested in the little details but more in the overall structure which is good to grasp at 1.5 speed.
@amantinband
@amantinband 2 жыл бұрын
Haha I'm a x2 speeder. I sometimes wish I could change real life to x2, but that's an indication I need to work on my patience 😂
@MrDimitri71
@MrDimitri71 2 жыл бұрын
​@@amantinband For me the main problem was the Copilot. A lot of times i couldnt read or associate what the method was doing. A feedback I want to give (Love this series btw) is to spend some time in the beginning explaining what is the structure you are sugesting (Maybe a drawing or something). Implementation details don't matter as much imo, but i really want to absorb HOW it was implemented -structure wise- and WHY, and that was why this video in particular got confusing. But anyways thanks for the informative content.
@saadaldulaijan4957
@saadaldulaijan4957 2 жыл бұрын
@@amantinband please keep the same speed, people who struggle following you can pause. I love how you making the video short with extensive useful content. Copilot is great 👍
Bike vs Super Bike Fast Challenge
00:30
Russo
Рет қаралды 23 МЛН
The CUTEST flower girl on YouTube (2019-2024)
00:10
Hungry FAM
Рет қаралды 45 МЛН
The FASTEST way to PASS SNACKS! #shorts #mingweirocks
00:36
mingweirocks
Рет қаралды 15 МЛН
Exceptions are evil. This is what I do instead.
24:41
Amichai Mantinband
Рет қаралды 20 М.
Stop Calling Your API a "REST API"
17:42
Amichai Mantinband
Рет қаралды 16 М.
Андрей Парамонов "MediatR не нужен"
58:40
Владимир Хориков - Validation and DDD
45:01
Конференция ArchDays
Рет қаралды 11 М.
Rust and RAII Memory Management - Computerphile
24:22
Computerphile
Рет қаралды 227 М.
How To Design Amazing REST APIs
18:57
Amichai Mantinband
Рет қаралды 15 М.
Lightweight In-Memory Message Bus Using .NET Channels
13:24
Milan Jovanović
Рет қаралды 11 М.
Making LINQ Blazing fast with PLINQ (Parallel LINQ) | .NET & C# Essentials
36:26
Bike vs Super Bike Fast Challenge
00:30
Russo
Рет қаралды 23 МЛН