Thank you. Is there are difference or preferable way to access the Service or all 3 way (2 from lecture and 1 from my comment) are equal and same performance-wise?
I also got the notification about the reply. Thank you for that too!
Because maybe I need to use this Service/Action only in that one method, and I don't need it for all Controller?
But if you use this class in more than one method, then yes, makes sense to define it in the Constructor.
Thank's a lot! If I understand correctly, when a class is used only once, we might as well instantiate it directly instead of going through a constructor?
Thank you for the lecture. Fairly easy to understand. Thanks for pointing out that we MAY take code out of Controller (put in Service or Action etc.). Could you please elaborate, when we SHOULD do it (and how it would benefit us later in development)? For example, when working on a larger project? Or - does it just depend on a developers personal preference? (By taking code away from a Controller I loose an overview, and it bothers me.)
The main benefit is the separation of concerns principle. Meaning separate parts of the code are responsible only for their individual action/job/task/whatever you call it. Then it is easier to work on improving/fixing THAT individual part of the code, without touching anything unrelated in any other files.
It's just easier to understand and work on 5 lines of code, than on 50-line Controller method.
Especially if you work in a team, and the code is opened by someone else in the future.
Or even yourself in the future, in 6 months you will totally forget what code you're writing today :)
Hello povilias sir, i am currently building a website where i have admin dashboard side and client side.. how do i separate service and action classes for admin and client side .. or sometimes some service or action logics are common for both admin and client side.. mybe we can call global services or actions ... How do i structure those service and action classes.
It's totally your personal preference, and depends on those "sometimes" cases as you described, how common and similar they are. Without specific debugging of the situation, I cannot advise on how to structure it.
May I ask you, let's say I'm working on an API and some condition doesn't pass, is it better to return error json directly from Services or just throw Exceptions and catch them in Controllers?
Service/Action class shouldn't "know" about what should be returned to the user, they are just internal classes. So if something goes wrong, you should throw exceptions.
Some exceptions are caught automatically by Laravel, or you can catch them yourself in the Controller.
How about adding "static" to execute action method?
// in the action (notice the "static")publicstaticfunctionexecute(array $data) :User{returnUser::create($data);}// in controller, no need for injectingpublicfunctionstore(UserStoreRequest $request){CreateUserAction::execute($request->validated());}
I don't think I have any repository specifically for that example.
In my cases, Service is a Service class without the interface, it's flexible for any changes.
Interfaces are for strict structure for MULTIPLE classes to implement that interface. I don't feel the need for multiple Services.
i am doing a Ridesharing project. Can you give me any suggestion, where i should use Interfaces?
Mainly, i write all the business logic in my service class. I didn't use interface before.
Waht architectural problem is solved by adding Services?
I see none, we just move code as it is from one place to the other, we get skinny controller and bloated service that mixes concerns and responsibilities.
I know what are services, but application should be divided into layers, ale logic of one layer should not leak into anoher - see Onion or Clean architectures. Just offloading logic to some random service is equally good as keeping it in controller or model.
You are technically right with this. Services indeed are usually 1:1 copies of lets say controller. But what this allows us to do is smart refactoring - move small action into its own method and use anywhere. Do you generate a slug? Well, move that into it's own function. Then you can use the slug generation without this exact action.
Or in other words - services are like transitional layer to something better. Moving away from services to lets say domain pattern or action pattern - is easier. This is because you will most likely refactor some of your code to be split into smaller accessible functions, so moving them - is faster.
ps. Services is just one of many ways to help you move into the right direction and are not a solution for DDD, Event driven, Action systems. It's more like a beginning step!
For me mixing application, domain and infrastucture layer and offloading it to additional file is the same as keeping it in one place, a controller.
I did not meant DDD when I mentioned Onion/Clean. Both acrhitectures just divide application into layers, leaving the Core/Domain a black box. They do not even mention what should be in it, and this is where DDD can be iplemented.
I do not think that movig code from one place to another helps in any way to apply any of those patterns you or I mentioned, and in fact services implemented like this very often are just a way to sweep unmaintanable, untestable code under the rug; and this was my point.
This is how my typical project build using Onion and implementing DDD is structured.
There are Application, Domain and Infrastucture Services and each of this services works in their own layer. Sometimes I also have something called "Tools" that contains for an example services that does not belong to any of the 3 layers (can be used in any of those, for an example observability service).
UserInterfaces (eg controllers) perpare the input and then execute a UseCase that belongs to Application layer. Each UseCase executes single "task" (eg CreateUser, UpdateUser) and is independent on UserInterface (can be run from RestController, HtppController, CLI or by job) and orchstrate application by interacting with it's services.
I can be honest with you - there is no one solution for this problem. What you described is true to some extent. Mainly, I would not agree with the:
this very often are just a way to sweep unmaintanable, untestable code under the rug; and this was my point.
As this is not the case. If properly done - services will be responsible for a single action and you can test them directly without any interaction on routes. In my case, services are the logic, which receives data from a controller/whatever and does an action. So one service method technically does 1 action based on the input it received. This is testable and in my experience - works without introducing a mess. So it does sound like the way you do the system, except ours is less dependant on interfaces/abstractions. Which I would argue is a better place to start and grow from there.
But then again, it does depend on the system. Some systems can do this, others should use more advanced things.
No it doesn't. If you write tests, yours are in 90% feature tests coupled with database and everything else that makes IO. I have few featue tests, and I try to avoid them because of how long they take (to execute).
Besides... since you do not have any architectural patterns implemented, then you have no strict rules to follow so you also can't write architectural tests that force developers to do things in certain way and avoid doing things in the way which they should not. This is where the mess beginins.
I can hand over my application to other developer(s) and get back to it after years. If dev(s) followed rules imposed by architectural concepts, I will be able to tell without looking at code from where in code what processes will be triggered, and where to look for that code. I can tell the same about applications that I have never seen before, but were created using those patters.
There is no difference between Action and Service in your approach. It is only contractual matter.
Better way is to make Action class invokable and calling it by
$action()
statement.PS. Improve displaying code blocks :D
+1 for the code block (it's needed, especially on this kind of site)
Would be great to have notifications about all replies to the comments. And see "My comments" list.
Adding both to the to-do list.
Comments notifications and Code block - great! Thank you.
you can see My Comments option now in your top-right menu
Can we get access to the Service by using "use" at the top of the file, like: use App\Services\UserService;?
And then i nthe code use it as: "$user = UserService::create($request->vadated())"
Yes, for sure!
Thank you. Is there are difference or preferable way to access the Service or all 3 way (2 from lecture and 1 from my comment) are equal and same performance-wise?
I also got the notification about the reply. Thank you for that too!
BTW, you can try to add/change those parameters to your "comments-comment" CSS class:
background-color:#334155; border-radius:4px; padding:16px;
so, they will fit the overall style of the site.
Yes, all ways to access ar equal and same, it's your choice.
I don't understand, why you don't use Dependency injection on your controller but you create a new instance of UserService ? :
With this, your controller does not have a strong dependency with the UserService.
Same case for UserAction.
Because maybe I need to use this Service/Action only in that one method, and I don't need it for all Controller? But if you use this class in more than one method, then yes, makes sense to define it in the Constructor.
Thank's a lot! If I understand correctly, when a class is used only once, we might as well instantiate it directly instead of going through a constructor?
Yes, you can instantiate if you want.
Do we need to register the service with a service provider?
No, Services are not the same as Service Provider. You can watch more about service providers here: //video/laravel-service-providers-all-you-need-to-know
Thank you for the lecture. Fairly easy to understand. Thanks for pointing out that we MAY take code out of Controller (put in Service or Action etc.). Could you please elaborate, when we SHOULD do it (and how it would benefit us later in development)? For example, when working on a larger project? Or - does it just depend on a developers personal preference? (By taking code away from a Controller I loose an overview, and it bothers me.)
The main benefit is the separation of concerns principle. Meaning separate parts of the code are responsible only for their individual action/job/task/whatever you call it. Then it is easier to work on improving/fixing THAT individual part of the code, without touching anything unrelated in any other files.
It's just easier to understand and work on 5 lines of code, than on 50-line Controller method.
Especially if you work in a team, and the code is opened by someone else in the future. Or even yourself in the future, in 6 months you will totally forget what code you're writing today :)
Hello povilias sir, i am currently building a website where i have admin dashboard side and client side.. how do i separate service and action classes for admin and client side .. or sometimes some service or action logics are common for both admin and client side.. mybe we can call global services or actions ... How do i structure those service and action classes.
It's totally your personal preference, and depends on those "sometimes" cases as you described, how common and similar they are. Without specific debugging of the situation, I cannot advise on how to structure it.
As always a good lesson.
May I ask you, let's say I'm working on an API and some condition doesn't pass, is it better to return error json directly from Services or just throw Exceptions and catch them in Controllers?
Thanks
Service/Action class shouldn't "know" about what should be returned to the user, they are just internal classes. So if something goes wrong, you should throw exceptions.
Some exceptions are caught automatically by Laravel, or you can catch them yourself in the Controller.
Got it, thanks
How about adding "static" to execute action method?
Yes that's another option but generally static methods are considered as "last resort" where nothing else fits well. At least in my experience.
How can i use Interface with Service File and call it in a Controller sir?
For examples of interfaces, I guess it's better you watch my course SOLID in Laravel
Appreciate it, Can you please share any existing example repositories of yours where u applied interface with service file?
I don't think I have any repository specifically for that example. In my cases, Service is a Service class without the interface, it's flexible for any changes.
Interfaces are for strict structure for MULTIPLE classes to implement that interface. I don't feel the need for multiple Services.
i am doing a Ridesharing project. Can you give me any suggestion, where i should use Interfaces? Mainly, i write all the business logic in my service class. I didn't use interface before.
If you don't need to use interfaces, then DON'T use them, why do you feel the need to use interfaces at all in this case?
Nice! Small tip, instead of a 'New file' you can create a 'New PHP Class` in PHPStorm so you dont have to set the namespace and class manually.
Waht architectural problem is solved by adding Services? I see none, we just move code as it is from one place to the other, we get skinny controller and bloated service that mixes concerns and responsibilities.
The service can be used in other places.
I know what are services, but application should be divided into layers, ale logic of one layer should not leak into anoher - see Onion or Clean architectures. Just offloading logic to some random service is equally good as keeping it in controller or model.
You are technically right with this. Services indeed are usually 1:1 copies of lets say controller. But what this allows us to do is smart refactoring - move small action into its own method and use anywhere. Do you generate a slug? Well, move that into it's own function. Then you can use the slug generation without this exact action.
Or in other words - services are like transitional layer to something better. Moving away from services to lets say domain pattern or action pattern - is easier. This is because you will most likely refactor some of your code to be split into smaller accessible functions, so moving them - is faster.
ps. Services is just one of many ways to help you move into the right direction and are not a solution for DDD, Event driven, Action systems. It's more like a beginning step!
Well, point of view depends on where you sit.
For me mixing application, domain and infrastucture layer and offloading it to additional file is the same as keeping it in one place, a controller.
I did not meant DDD when I mentioned Onion/Clean. Both acrhitectures just divide application into layers, leaving the Core/Domain a black box. They do not even mention what should be in it, and this is where DDD can be iplemented.
I do not think that movig code from one place to another helps in any way to apply any of those patterns you or I mentioned, and in fact services implemented like this very often are just a way to sweep unmaintanable, untestable code under the rug; and this was my point.
This is how my typical project build using Onion and implementing DDD is structured.
There are Application, Domain and Infrastucture Services and each of this services works in their own layer. Sometimes I also have something called "Tools" that contains for an example services that does not belong to any of the 3 layers (can be used in any of those, for an example observability service).
UserInterfaces (eg controllers) perpare the input and then execute a UseCase that belongs to Application layer. Each UseCase executes single "task" (eg CreateUser, UpdateUser) and is independent on UserInterface (can be run from RestController, HtppController, CLI or by job) and orchstrate application by interacting with it's services.
I can be honest with you - there is no one solution for this problem. What you described is true to some extent. Mainly, I would not agree with the:
As this is not the case. If properly done - services will be responsible for a single action and you can test them directly without any interaction on routes. In my case, services are the logic, which receives data from a controller/whatever and does an action. So one service method technically does 1 action based on the input it received. This is testable and in my experience - works without introducing a mess. So it does sound like the way you do the system, except ours is less dependant on interfaces/abstractions. Which I would argue is a better place to start and grow from there.
But then again, it does depend on the system. Some systems can do this, others should use more advanced things.
No it doesn't. If you write tests, yours are in 90% feature tests coupled with database and everything else that makes IO. I have few featue tests, and I try to avoid them because of how long they take (to execute).
Besides... since you do not have any architectural patterns implemented, then you have no strict rules to follow so you also can't write architectural tests that force developers to do things in certain way and avoid doing things in the way which they should not. This is where the mess beginins.
I can hand over my application to other developer(s) and get back to it after years. If dev(s) followed rules imposed by architectural concepts, I will be able to tell without looking at code from where in code what processes will be triggered, and where to look for that code. I can tell the same about applications that I have never seen before, but were created using those patters.
It's better for the create method of the service class to take a DTO as an argument, as it provides more predictable and understandable behavior
For the implementation to be perfect, the service class should use an interface implementation that interacts with the infrastructure.