Loved the explanations and everything. Quick thing to add and probably a lot of users do it differently. Using your service as the "Business layer" doesn't mean you write bad code or not clean code. My humble opinion is that, "controllers" should take care only for input and output of the application, nothing else. Service is actually the business part and the clean code should be there. You have to think also about the architecture and controllers should not do business logic. Ofc repository,dao or whatever for the data layer. Keep with the great stuff :)
@mundoprogramado3106 Жыл бұрын
I was two days ago trying to pass the repository linked with the interface in usecase. Find out at 10:43 that it needs @Inject
@tuanpham61629 ай бұрын
Yes, I agree, too. I also think it is fine if we let service handle its business logic instead of laying it on controller. I don't want to split my controllers just because it is too long to handle like he recommends for the SRP :(
@devrodox8 ай бұрын
yes! this is very important from an architecture's perspective, let's say for example ports and adapters architecture, where you should encourage such decoupling that even you can switch the controller implementation (from example moving from a rest controller to a kakfa topic subscriber) and the business logic should stay the same.
@TheBeastDispenser Жыл бұрын
Thank you for including good and bad examples! By far the best way for me to learn
@reidyoung29810 ай бұрын
Fantastic way of teaching these concepts and one I have hoped to see for years now: real world issues people create constantly, why they are mistakenly created, how to avoid them, and how best practices (SOLID, etc.) guide us to avoid making such mistakes along the way to creating more composable code. Thank you for the video!
@permanar_ Жыл бұрын
I really love this NestJS series. Please keep going!!
@cheng6630 Жыл бұрын
I think logic is not handled on the controller, the controller only forwards requests from view to service and receives response and forwards to view.
@justfromnowhere10 ай бұрын
I thought it was a bit abstract but he ended up saying it should be handled in another layer, rather than the service (this layer can communicate between different services and will be called from the controller). But he gave an example from the controller so you feel it's not quite right. But I understand what he thinks.
@TMANandMAISON9919 ай бұрын
Bruh all this stuff is just opinions. There is no correct answer
@petertran1416 ай бұрын
@@justfromnowhere well then what is the correct answer for this? if you have more class to just serve a small function, your project will become very very big.
4 ай бұрын
@@TMANandMAISON991 why not write everything in one big file with goto statements? roflmao
@araz9114 ай бұрын
you are violating KISS principle
@abolfazljalildoost76611 ай бұрын
that was facinating. please provide more nestjs videos
@georgy2763 Жыл бұрын
I am confused with example on GitHub for open closed principle. Should we call registerPaymentGateway in controller? Will this object (paymentGateway) always have only 1 payment method at a time? I thought paymentGateways (the one in paymentService) should have all our relative payments options inside the object, so that when we call processPayment it checks payment method against the one we have. I am just confused the way it’s organised in your GitHub repo) I didn’t even see where you are calling processPayment Method in your code
@CharlesDv Жыл бұрын
Excelente video. Just a comment, at 4:09 ordersService should only receive a DTO, how the service implements the solution is not concern to the controller.
@MAVrikrrr Жыл бұрын
Don't get the implements against extends part. "extends" is not bad thing and it still covers Liskov principle. If you want to force one (or several) of methods to be implemented in children, you just make the base class abstract and make those methods abstract as well (just like you did in open-close example). "implements" is good when you combine multiple interfaces in one class implementation. But "extends" allows you exactly *extend* something (not re-implement from scratch). Good overview though.
@romarioputra37753 ай бұрын
Yeah, LSP is not about using implements instead of extends
@geebsayshi Жыл бұрын
In OCP you can extend if the subclass is the same as the base class but with an added functionality. e.g A cock is a bird that can crow. Cock class can extend the bird class which has the fly functionality and then implement its own crow functionality.
@craigsmith37805 ай бұрын
Good video. Since the PaymentGateway and StorageFactory do not share code across their respective implementations, they would be better suited as interfaces as opposed to abstract classes. A good general rule to follow is that, if there is a need to share code across multiple implementations use an abstract class to achieve this, otherwise an interface is all you need.
@andyheld313610 ай бұрын
Thanks for that video. How do you recommend injecting all implementations of services in one array with the dependency inversion principle? In your Scenario you have 2 Service implementations and let's say you want to inject List services. One method is: Module factory methods or the use Value in the module file. But it becomes more complicated when the service implementations are in different modules - i do not want to import all the modules, which implement them, just for defining an array of services. What i do currently is a service provider module with an abstract ServiceProvider class with a registerService(service: T), and a getServices():T[] method from a ServiceProviderModule. It holds a list of instances of type T. All Implementations of these service providers define their abstract type, in your case it would be class StorageServiceProvider extends ServiceProvider. The service implementations just inject the StorageServiceProvider and in the constructor they just register themself with storageServiceProvider.registerService(this). A consumer service, which needs all storage implementations injects the StorageServiceProvider and calls getServices() method and can iterate over them. I am coming from the java spring world and there it is already handled implicitly. Is there a in house solution in nest for handling list of services with the dependency inversion principle? :) Thx
@belkocik8 ай бұрын
Would love to see a good course of Nest.js with these clean-code - SOLID principles.
@vipulmaurya96733 ай бұрын
i'm also want from wscube tech team
@mohamedsba418510 ай бұрын
very helpful. thank you and keep doing great stuff
@EllisDosAU4 ай бұрын
basically OCP, LSP and DIP are very similar, as per video in OCP payment methods can be added, LSP different payment strategy can be used, and DIP allows using one line to switch between different class implementations, all examples are pretty close to each other
@RdozeTV Жыл бұрын
In single responsibility principle you could also use events to decouple
@HusamAlmaher Жыл бұрын
nice bro please keep updating us with your awesome knowledge about backend specially nest js
@yohanneskindu8794 Жыл бұрын
Dude you are very amazing developer, I was just looking around to improve my coding structure and make it more readable, reusable and maintainable, This is the video anyone who wants to look first before writing nest js code. Thank you!!
@The14Some1 Жыл бұрын
hey @CoderOne, don't you think that on 4:00 your controller does too much of logic? I've been taught, that controllers should only transfer the data from view to services and back. What would you do if there will be addtitional logic between creating order and sending it? For example, let's imagine you must create orders without restrictions, but send action should be applied only after some filtering. would you add this logic right in your controller between two service calls?
@vinimaciel11 ай бұрын
It has no logic operations, just calling functions, if you need to check another thing, maybe process data or validate it, you'll have another service
@tuanpham61629 ай бұрын
@@vinimaciel I don't think so, because sometimes, we also need to check the other service call is fine or have errors to process next steps . Do you have ideas when we face this case ?
@ubonginyang1889 Жыл бұрын
Nice video man. However, I prefer to use extend, and then make the method in the base class an abstract method as well.
@DenNivAs Жыл бұрын
The controller can be replaced with another method because it should not contain business rules. Controllers are responsible for handling requests and delegating the processing to other components. By keeping controllers lightweight and decoupled from business logic, it allows for flexibility and easier replacement with alternative methods or technologies.
@martonvalentin7386 Жыл бұрын
That's right, but I'm always wondering how and where should I put these wrapper implementations.. How do you use it usually? For example when you have to save something and also sending notification, you should not put both different service calls into the controller (as you mentioned), but how would you call that service that wraps the business logic? I would usually inject my abstract notification service into the service that saves the data, and call the sendNoti method inside the "saving" method
@DenNivAs Жыл бұрын
@@martonvalentin7386 This is a very used solution, mainly by frameworks. Another option is to create an event within your service/use case to make this call more decoupled. Then the event of sending the notification will be responsible for sending it, being able to put it in a queue and not depending on the flow of the notification to confirm the creation. Imagine that your notification throws an exception, it would break your creation which is another case, thus breaking the single responsibility principle.
@danielosariemen382410 ай бұрын
Great content, really learnt alot from this video
@palychbasist5 ай бұрын
SPR doesn't mean "class should do only one thing". Classes or modules do a lot of things. SPR means that class or module "should have only one reason to change". It means that when you have to change orders processing you shouldn't make changes in other parts of your application e.g. users, accounting etc. And the orders module still does a lot of different things.
@miguecast11 ай бұрын
It's the first time I see an exemple of Record type in real world, thank you!
@SabujArefin6 ай бұрын
Great explanation. Thanks
@-_-unseen-_-9 ай бұрын
The Open / Close Principle (Objects or entities should be open for extension but closed for modification.) has nothing to do with DI. The "D" in SOLID is where IOC or DI would come into play. Open / Close is more about coding against a contract rather than a concrete implementation. So in other words, use interfaces and abstract classes.
@MichelVersianiDev Жыл бұрын
Amazing as always, thanks for the tips!
@ODAIR_SCTY_OFC Жыл бұрын
good video, like from brazil.
@-_-unseen-_-9 ай бұрын
Single responsibility means that your controller is not responsible for sending emails. Controllers are only responsible for handling the http request / response and invoking the business logic layer. In frameworks like nestJs that includes all the validation and transformation of the endpoint input as well. If you remove the presentation layer from your solution can it still orchestrate the use case?
@gamingwolf3385 Жыл бұрын
The last time i want to learn more about this framework , but i didn't get a large community as other frameworks
@jq_dev Жыл бұрын
Amazing tutorial, thank you!
@beodan9219 Жыл бұрын
great video thank for your sharing
@neallahiany22139 ай бұрын
Hello, what's theme were you using on the video ? Thank you
@EstebanHelgueroCardiff Жыл бұрын
Really good video!
@muhammadsalmanagustian75 Жыл бұрын
amazing, thanks for the tips. +1 subs
@eminaliyev4953 Жыл бұрын
Very helpful!
@TGamer2209 Жыл бұрын
very good video =))
@sitdownandcode10 ай бұрын
"Make no mistake, there is a principle like that. A function should do one, and only one, thing. We use that principle when we are refactoring large functions into smaller functions; we use it at the lowest levels. But it is not one of the SOLID principles-it is not the SRP." page 62 of Clean Architecture by Robert C. Martin
@addliam Жыл бұрын
Very awesome. Thx
@staspanyukov4822 Жыл бұрын
Unfortunately not many js developer are even noticed about these principles
@dimitrisbellos014 ай бұрын
Hey, I am looking for a setup for test suites in NestJS, but with addition of factories for classes, in order to help me with seeding and "Arrange" Step of the Test. Any idea where to watch that? Especially, for complex schemas where i.e. I want to test a module, which every entity depends on the creation of others.
@s1dev Жыл бұрын
soo good, would you make more videos on nestjs design concepts
@NofaceAndrew Жыл бұрын
Why are you using Abstract class with abstract method Payment Gateway instead of interface in 7:19?
@HannyFransis Жыл бұрын
great tips keep going
@-_-unseen-_-9 ай бұрын
If your code inside your service method throws an error, does the email still get sent? In your case no but it's because you don't have any error handling not because it's part of the use case. You would have to add some additional business logic to your controller in order to decide if the email should get sent. Oh, and your product manager just asked you to send a certain type of email based on the response from the database when adding a new order. Now you have to add even more business logic to your presentation layer because your business logic layer does not complete the use case. As the use case grows so do your problems given your implementation.
@patel55327 ай бұрын
Can we structure nest js project similar to Spring boot? I mean separate the files in Controllers, Service, Models etc folders. Is it good idea or practice?
@Mak-Henry Жыл бұрын
a genius
@nhatnguyenhuu7822 Жыл бұрын
I have a doubt about the S principle, if do it like this, the code in the controller is quite long, and corresponds to business, somehow it is not good for reusable functionality right? Just kinda view from mine! Anyone can help me on it? Or do we have to make trade-offs?
@ulrichmbouna40917 ай бұрын
How do you Handle Money in such situation? In Laravel they use moneyphp
@davidchavez4054 Жыл бұрын
Is there any reason for using abstract classes instead of interfaces?
@portgasBeeAzul Жыл бұрын
Very good question but no answer ! too bad.. I would like to get answer, really !
@thomass9802 Жыл бұрын
Interfaces do not exist at runtime in Typescript, so it is not possible to resolve dependencies by interfaces (unless you use a String token that has the same name as your interface and use the @inject() decorator in your constructor)
@ayomidewilfred18645 ай бұрын
I think controller doesn't have a larger scope compare to service. Service handles all the logic in our application. It is not good to bogus the controller, let service do the logic.
@carpamon Жыл бұрын
Doesn't StorageFetcher breaks LSP?
@slahomar1497 Жыл бұрын
in 8.17, when you're filling the paymentGateways ?
@jonamep Жыл бұрын
I thought a concrete class should only implement interfaces not abstract classes. Why ts allows that ? Inheritance from class to class I normally use extends. If I want to enforce contract I would use implement from class to an interface
@monastyrskiidenАй бұрын
The problem with the SR principle is how you decide what is a single responsibility. Where to draw a line? Uncle Bob clearly said in his book that the SR is not a single fn call The SR means that your method should care only about a single piece of business logic like in your case processing the order. It may involve multiple steps. He's saying parts that have a single common reason for change should live together. Sending an email is a valid part of submitting the order, you want your users to know that the operation is successful and their order is received and processed. In this case, it should live within the service. I guess, you wouldn't want your users to spam you with calls to confirm whether or not you received their order just because you forgot to call an email service after you submitted their order.
@jo.repossi Жыл бұрын
Can you create a nestjs tutorial serie?
@DanielNistrean10 ай бұрын
What is user can select any of the payment providers ? Your solution doesn't include that.
@dksss1 Жыл бұрын
Hey great video, why the storage fecther is an abstract class and not an interface
@vipulmaurya96733 ай бұрын
pls make course for nest.js
@josephjoey3904 Жыл бұрын
How does this architecture work with state management sayusing context api or redux toolkit?
@lardosian Жыл бұрын
This is a backend framework, does not deal with state management
@josephjoey3904 Жыл бұрын
@@lardosian oh, I read that as Nextjs either way, very informative video
@lardosian Жыл бұрын
@@josephjoey3904 Easily done, but lots of videos covering what your after - eg React Query for example..
@seghirissam26628 ай бұрын
please what the theme name you use in vscode ?
@CoderOne8 ай бұрын
Halcyon! I need to do a video about it soon 😅
@isi10446 ай бұрын
talking about giving urself extra work
@adiathasan Жыл бұрын
🚀
@balasuar9 ай бұрын
Aren't these just basic OOP patterns rebranded for javascript devs?
@jongjong2x7 ай бұрын
i definitely agree, they're just trying to do java in typescript :D
@albertlabarentojr16257 ай бұрын
Naming a class suffixed with "Service" doesn't make SRP easier, class named as per its responsibility not only enforces the developer to write code in SRP but also for readability, there's no need to name a class called "StorageS3FetcherService" if you can name it as "StorageS3Fetcher"
@miguecast11 ай бұрын
If you want to call othe method from another service inside a service and avoid to inject this another service, you just can emmit an event and put this other method listen to it.
@surenmatinyan36999 ай бұрын
The domain logic should not be inside the application layer in your case you show that when you call the email method inside the controller of orders! There can be a lot of logic from other modules so what you will do in that case is all the logic will be both of them in controllers and in services that's the antipattern That's wrong!
@UrzaRage7782 ай бұрын
In your "LSP example", you say, "You don't have to change any code, etc", but you do; you're manually changing the strategy being used via the injection in the controller. How would you go about programmatically determining this? Eg: Activating the sale pricing either based on different times of the year, or being able to arbitrarily use sale pricing. This seems like a bit too contrived of an example that may lead people down an arguably incorrect path.
@TheAdnanZaib10 ай бұрын
This guy is using coding structures that junior developers use till they learn how to properly code. This video is a waste of time in my opinion.
@matejpesl18 күн бұрын
This is monstly not very useful in large codebases.
@-_-unseen-_-9 ай бұрын
You totally shot yourself in the foot when you decided to add the sendOrderEmail() in the controller. Sending a notification, in this case an email is part of your business use case. Your service class is responsible for orchestrating the use case. Look at it this way. If you remove the API presentation layer (controllers) can your app still orchestrate the use case? In your case no. You can imagine there may be a number of things you could put in place of the API presentation layer like going from REST to GraphQL or a grpc microservice or even a CLI. Your implementation does not scale given your decision to put business logic inside the controller. Your giving bad advice here ( kzbin.info/www/bejne/rHaaZZqkq5mJors ). The service class that handles the submitOrder use case should invoke the process of sending an email. If you really want to look like a senior dev then you would suggest dispatching an event once the order is created successfully and allow any number of operations to subscribe to that event one of which may be sending an email.
@-_-unseen-_-9 ай бұрын
kzbin.info/www/bejne/rHaaZZqkq5mJors "you can change the pricing strategy without changing any code", but you changed code to use the other strategy! What you need is a factory that will provide you with the desired pricing strategy based on some context or other condition.