Laravel Controller: Move Logic to Action or Service Class

  Рет қаралды 36,013

Laravel Daily

Laravel Daily

2 жыл бұрын

In this live-coding experiment, I will try to move the logic outside of the Controller, and create an Action class, and later a Service class, performing the same thing. Which one do you prefer?
Video of Creating That API Controller: • Laravel API Controller...
Pull Request to API Challenge: github.com/LaravelDaily/Larav...
- - - - -
Support the channel by checking out our products:
- Enroll in my Laravel courses: laraveldaily.teachable.com
- Try our Laravel QuickAdminPanel: bit.ly/quickadminpanel
- Purchase my Livewire Kit: livewirekit.com
- View Laravel Code Examples: laravelexamples.com
- Subscribe to my weekly newsletter: bit.ly/laravel-newsletter

Пікірлер: 116
@JimOHalloran
@JimOHalloran 2 жыл бұрын
I’m not keen on the abort calls in the action/service class. I think one of the main responsibilities of the controller is to decide which response should be returned (although the content of that response might come from a template or API resource, so having some responses in the service or action, and others in the controller doesn’t seem right to me. I could easily imagine coming to a project like this somewhere down the line and trying to figure out why it’s returning a 500 result all of a sudden. In this case I’d hope to be able to see the abort call in the controller itself rather than having to dig through the action service classes to find it, especially if they’re complex. Throwing an exception out of the service would be my preferred option for this reason.
@LaravelDaily
@LaravelDaily 2 жыл бұрын
You're right, well explained
@demonaudio2563
@demonaudio2563 2 жыл бұрын
Exactly.
@aleksandarkrasic8324
@aleksandarkrasic8324 2 жыл бұрын
Exactly, services should return null if there is an error, and controllers should abort if variable content from service class is null.
@DanAbrey
@DanAbrey 2 жыл бұрын
Totally right. Decoupling to an Action is pointless if you're passing in a request to the action. Your Action is coupled to the request, it's no longer independently callable or testable.
@DanAbrey
@DanAbrey 2 жыл бұрын
@@aleksandarkrasic8324 return null if there's an error? Why? That's what exceptions are for if it's something that the application should be handling (ie if it's something you're checking "if null then do this") Null means empty, nothing. Not error.
@andrewwwlife
@andrewwwlife 2 жыл бұрын
As for me one of the main criteriums of a good application is the ability to call core logic from console, that's why I'm a huge fan of services that I can call from every place in my application
@dalok100
@dalok100 Ай бұрын
This reminded me of the correct way to use controllers, a concept I learned years ago with the Spring Framework. While others suggested using services in the comments, the simplicity of actions made it easier for me to understand and cleared the way for further learning. Thx!
@michalbabic8636
@michalbabic8636 2 жыл бұрын
1/ Checking, if someone can or can't do something is responsibility of Request (or Gate if necessery). You use authorization method in request always as true. But you can move this logic here. In single responsibility principle, store method is not about checking user. 2/ For this reason I preffer service layer which each part of logic is separated. Request checks user authorization and validate inputs. If is needed, throws exception which is handled by Exception Handler. Next Controller call service layer which call all neccessery service methods. If is no exception throws, model is returned to controller and controller make response - ideally through Resource layer. 3/ This approach is nice for later adding new features without updating existing code and for writing unit tests (one for request, other for services) and one global as integration test with calling endpoint and testing valid response structure.
@feryadialoi2244
@feryadialoi2244 2 жыл бұрын
The action is more popular called by Command Pattern, when every method in service make the service class too big to maintain then every method moved to one class to maintain individually
@maurovalvano5707
@maurovalvano5707 2 жыл бұрын
But a lot of time, a service method can call another service method and it's more easy and fast to fix them both. I hate to jump from a file to another and back
@feryadialoi2244
@feryadialoi2244 2 жыл бұрын
@@maurovalvano5707 that's right, every way have their own pro cons, in action/command doesn't mean you can't have another method except the main/action one, you still can have the provate method, or even call another service/command, from constructor or another way
@daleryanaldover6545
@daleryanaldover6545 2 жыл бұрын
I've seen the service implementation on my previous rails job, didn't know I could do it with laravel too.
@jacquesmatike9289
@jacquesmatike9289 2 жыл бұрын
Services are more interesting because as it has many methods, the service is not directly related to the main controller. Then another controller could have a need of one method of that service. For example having a paymentService that has a create_wallet(), that method could be called from any other class like a listener to create user wallet when any new user registration. Be in an handle method couldn't be that easy
@hederperez7336
@hederperez7336 4 ай бұрын
Iam applying this knowledge to my proyect rigth now, and i like how looks the code
@mmohamedbadr
@mmohamedbadr 2 жыл бұрын
Thank you, it's great video
@NSlides
@NSlides 2 жыл бұрын
Cool stuff.. we are using services approach..
@nirajgautam403
@nirajgautam403 2 жыл бұрын
Already working with these techniques
@izzymane9591
@izzymane9591 2 жыл бұрын
keep doing this gods work
@sateesh.ilavenil
@sateesh.ilavenil 2 жыл бұрын
Thank you so much for the video. Instead of a try/catch in each controller method, can we not have a global Handler.php(as given by Laravel) which handles anything that is not caught by controller & service/action?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Yes, that's also a good practice, but depends on the scenario, how many of the exceptions are "standard" to be caught by a Handler, or how many of them are individual, so should be caught in Controller.
@mohamadcheaib
@mohamadcheaib 2 жыл бұрын
In my opinion, in the action class the handle should return voice, but in your code in some condition it returns voice in other condition it returns void. Then in the controller you recheck again the voice if it was recently created, which is a repetition, so the handle function should return voice and the conditions should be in the controller based on the returned voice object. I dont know maybe i'm wrong but i prefer the insert update logic of controller to be in the controller and seperate the logic only in one case if i'm sure that the logic will be reused in other classes or methods
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Fair points about inconsistency, agree it could be improved. But I disagree that it should be in Controller if it's 10+ lines of code, it should be some separate class, just maybe structured better than I did.
@NehalPatelTheBest
@NehalPatelTheBest 2 жыл бұрын
Great content sir, this way we can handle request from frontend and API from the same Action/Service class logic. Can we implement this Service/Action class with livewire components?
@invgreat5608
@invgreat5608 Жыл бұрын
THANK YOU!!!!! 🥰
@soopercoco91
@soopercoco91 2 жыл бұрын
I usually create actions as invokable classes just for keeping things clean.
@amrullahdev8895
@amrullahdev8895 2 жыл бұрын
thanks for all the tutorials that you've made, I've been watching your video about optimization lately but is there any way to StressTest LaravelApp, I currently using artillery for that, but I don't quite understand, would u like to make a video about stress test?
@Code2Master
@Code2Master 2 жыл бұрын
thanks a lot❤
@antonlindell6102
@antonlindell6102 2 жыл бұрын
Love your videos, thank you for a great resource. Are you planning on making a video of Laravel Octane, with pros and cons?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
No, haven't used it
@antonlindell6102
@antonlindell6102 2 жыл бұрын
@@LaravelDaily I see. I would love to see you trying it and hearing your thoughts, to me it seems incredible but have yet to try it as well.
@LaravelDaily
@LaravelDaily 2 жыл бұрын
From what I've read about it, it would be useful for 0.001% of Laravel projects. So for now, not planning to shoot a video on that topic.
@69leostereo
@69leostereo Жыл бұрын
nice video , could you please explain, why ... controllers should be short ?
@mdranacse19
@mdranacse19 2 жыл бұрын
Thanks ❣️
@rakeshthapa9541
@rakeshthapa9541 2 жыл бұрын
I believe the main purpose of single responsibility classes is to promote code re-usability. Lets say I need to do the same action for api/web/command then the best thing would be to take all the logic into one place and use it everywhere and send the response as per where it is used. If I am using the action in api controller then handling the status code and returning data as json structure is the controller responsibility similarly if used in web it is the controller responsibility to either send some html or redirect to another page. What I don't like in this video is that you are passing Request class as an argument to the action class which will limit the reuse of the action class as the request structure will be different for api/web/command so we should rather work with something like DTO (a plain class which contains almost no logic and contains only information needed to do the action). In this way your action class will be independent of how the request is made and hence can be easily tested without doing any http calls. Most of the time you don't need to do this but if you want to make you controller shorter then just use service classes(or model or private/protected method in the controller) to hide your code from controller to somewhere else and don't separate the logic into many classes because as the project grows you will have hundreds of classes and it would be much harder to debug. Moving logic into multiple place is always pain in the ass So if you want to do it, then do it properly, write tests for your classes so that you can find out if there is any problem more easily(but still you will struggle) . And lastly for me, most of the time I use laravel for building api only and all the logic goes into controller or some service/helper class and yeah no tests(in general).
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Thanks for the valuable comment, a few valid points. I wouldn't use DTO, but probably would change Request class to a few exact variables which would be used in Action. But then it's more like a Service.
@rakeshthapa9541
@rakeshthapa9541 2 жыл бұрын
@@LaravelDaily sure but then I would also remove the request clsss typehint in the action.
@AfmpJR
@AfmpJR 7 ай бұрын
06:11 I saw you recommending in another video (Jr code review) to not leave the abort for the service, since it's not supposed to do that, but throwing an exception to the controller, which is the right place to do such thing.
@LaravelDaily
@LaravelDaily 7 ай бұрын
Services should inform controllers that something went wrong. Controllers need to CONTROL, meaning decide what to return to the user if that something went wrong.
@gamerneversleep4200
@gamerneversleep4200 2 жыл бұрын
I am new to laravel. What is good practice for backend + blade components?
@godstimejohn2673
@godstimejohn2673 2 жыл бұрын
Thank you, I love your videos. Can you please do a video on how to use both actions and service?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Isn't it the same what I just did?
@godstimejohn2673
@godstimejohn2673 2 жыл бұрын
@@LaravelDaily ok the question should have been, what scenario can we combine the two patterns (service and action). Maybe we have a service that also uses action.
@jacquesmatike9289
@jacquesmatike9289 2 жыл бұрын
@@godstimejohn2673 it's already explained in the video bro
@godstimejohn2673
@godstimejohn2673 2 жыл бұрын
@@jacquesmatike9289 ok. I will have to rewatch it (maybe I watched it in a hurry at first). Thanks bro.
@ling6701
@ling6701 2 жыл бұрын
Thanks. So if I understand correctly, the action class is just any class with no particular laravel magic. It's just a convention that would have worked in any framework with dependency injection ?
@ayoubjamouhi6890
@ayoubjamouhi6890 2 жыл бұрын
I do dependency injection of service in controller
@VadimBesedin
@VadimBesedin 2 жыл бұрын
Is there an instruction or an article that explains the difference and best practice usage cases for all the types of Laravel classes? Actions, Helpers, Jobs, Services, etc...
@LaravelDaily
@LaravelDaily 2 жыл бұрын
I haven't seen anything like this. Maybe it's a signal that I should do it myself :)
@VadimBesedin
@VadimBesedin 2 жыл бұрын
@@LaravelDaily With your explanation skills - That would be great!
@user-gt2eh8ne2x
@user-gt2eh8ne2x 2 жыл бұрын
Hey, I have a question. How Laravel passes VoiceAction or VoiceService in your controller method as input parameter?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
It's a long thing to answer, I may shoot a separate video about Laravel Container and its logic, can't answer in a comment.
@user-gt2eh8ne2x
@user-gt2eh8ne2x 2 жыл бұрын
@@LaravelDaily okey, thank you, will watch it :)
@mohamedahmedradwan9367
@mohamedahmedradwan9367 2 жыл бұрын
@@LaravelDaily please do
@rizkypujiraharja
@rizkypujiraharja 2 жыл бұрын
can't wait for this :) thank you
@akunbeben
@akunbeben 2 жыл бұрын
in a nutshell, it's similarly like Dependency Injection cmiiw
@JuanMarchant
@JuanMarchant 2 жыл бұрын
Hi. This same example but on livewire component... Where inyected this new action class o service class on livewire component. Thnaks
@LaravelDaily
@LaravelDaily 2 жыл бұрын
It would be the same, just change Controller to Livewire component, and inject classes that you need.
@squattingnomad6298
@squattingnomad6298 2 жыл бұрын
Services don't require registration and binding to app?
@Sinres2
@Sinres2 2 жыл бұрын
What do you think about use __invoke magic method to call action class?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
I don't see a big difference between __invoke() and handle(). To me personally, __invoke() is associated in my mind with invokable CONTROLLERS and not other classes: laravel.com/docs/8.x/controllers#single-action-controllers
@helluci6449
@helluci6449 Жыл бұрын
Does that count as a "bad practice" if I create multiple Actions, then just call those in Services?
@LaravelDaily
@LaravelDaily Жыл бұрын
No
@ugayashan8659
@ugayashan8659 2 жыл бұрын
Hey L.daily I'm working on a laravel API. in the User service method I have a function called refreshJwt and I'm trying to get Auth::id which is returned in loginUser function in the same service class, inside the refreshJwt function to generate JwtToken, but it is null. is there any workaround?? I tried getting user id from the session as well, they didn't work
@bm-software
@bm-software 4 ай бұрын
Not sure if I understand you correctly, but It seems you need user details from Auth Facade. Try below Auth::user()->id;
@bekkarghezal6173
@bekkarghezal6173 2 жыл бұрын
Thank you for these very useful little free lessons, Can you please, tell me how to create laravel str helper, as diffHuman or plural ..., also, I would like to create a PHP script for HTML rendering,
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Helpers: kzbin.info/www/bejne/pKSrhGSbaraCj9k And: laravelexamples.com/tag/helpers HTML rendering: can't answer that in a KZbin comment, too broad question.
@bekkarghezal6173
@bekkarghezal6173 2 жыл бұрын
@@LaravelDaily Thanks a lot
@JhErEl9
@JhErEl9 2 жыл бұрын
thanks, I've a question, the transactions should go in the service or in the controller?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
What do you mean by transactions?
@JhErEl9
@JhErEl9 2 жыл бұрын
@@LaravelDaily laravel Eloquent manual transaction, with try/catch
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Oh, I see. Not sure, they could go in either class, it's your choice.
@muhammadhateem3090
@muhammadhateem3090 2 жыл бұрын
@laravel Daily, i want to perform some business logic on the $request which is coming through view, so should i use a service class for that business logic as i should not put it into controller? can u answer or suggest any video who is doing the same.
@LaravelDaily
@LaravelDaily 2 жыл бұрын
What exactly do you mean by business logic? Can you provide code example? (May be unfinished code)
@muhammadhateem3090
@muhammadhateem3090 2 жыл бұрын
@@LaravelDaily like i want to transfer amount from one account to another account, and i am getting the amount from my view, while the accounts are stored in db.from business logic I meant any logic that is more than simply one line of code.
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Ok, I see. Then I guess any external class would do, Service is the most typical example.
@glmarco24
@glmarco24 2 жыл бұрын
I always check earlier things like $question->user_id == auth()->id(). I would create middleware isQuestionOwner and abort there. It aborts earlier, it may be reused in another controller and looks cleaner and more separated to me. How do you feel about that?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
But can it be used in an Artisan command? In a unit test?
@glmarco24
@glmarco24 2 жыл бұрын
@@LaravelDaily you can write separated tests for service and for middleware also, though I am not feeling sick when I don't have 100% coverage. Not sure about artisan command, maybe it's possible to trigger middleware in constructor method
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Yes, you're right, it is POSSIBLE. But not convenient, in my opinion. Again, it's all a personal preference, so use whatever works for YOUR case.
@glmarco24
@glmarco24 2 жыл бұрын
@@LaravelDaily that's true. However, you might end up with "never use middleware", because "unit tests and artisan command" can always apply to any middleware
@Aalii6
@Aalii6 7 ай бұрын
👍👍
@kerolesmonsef4179
@kerolesmonsef4179 2 жыл бұрын
what is the different between action and repository pattern
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Watch some videos here mentioning repository patterns, and you will feel the difference: kzbin.info/door/TuplgOBi6tJIlesIboymGAsearch?query=repository
@abdulbasitsalah2918
@abdulbasitsalah2918 2 жыл бұрын
hello Povilas i filtering my orders using get method (not POST), when the text field is empty, the request value for that field will be empty string, in that case, it will be true in the $request->has and the where condtion that apply to the model, inside the if will be executed and it return [] array Order::with('user') if ($request->has('brand')) { //return 'has brand'; $query->where('brand', trim($request->brand) } i that any way the $reqeust->has() not pass empty string ?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
You need this: laraveldaily.com/less-know-way-conditional-queries/
@abdulbasitsalah2918
@abdulbasitsalah2918 2 жыл бұрын
@@LaravelDaily thanks thats a great tip and alos i find anther solution "insteat of $request->has using $requtest->filled()" that way it only that condtion will be true if the value for input exist
@ShotoCon
@ShotoCon 2 жыл бұрын
To abstract data from the controller for a 3rd part API integration, would you use a Service Provider (as in the final example), or create a package, or a combination of the two? If you have a video or article, I can review, it would be greatly appreciated.
@LaravelDaily
@LaravelDaily 2 жыл бұрын
It depends on the exact integration and how it should work. I don't really like theoretical question, I like practical examples with the exact situation/problem and then I can work on the answer.
@javieru5871
@javieru5871 2 жыл бұрын
In this context, an Action and a Service are both referring to the same concept application?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Not really, Action is usually for one single action, like a Job, and Service are usually for many methods grouped for some purpose.
@javieru5871
@javieru5871 2 жыл бұрын
@@LaravelDaily Ok I see, so for example, a Service might be appropriate for a set of CRUD methods or many public methods designed for certain business purposes around a Model Entity, while an Action is just one single public entry point maybe with many private properties inside to achieve some certain functionality not necessarily related to a Model.
@fahimanzam7015
@fahimanzam7015 2 жыл бұрын
Do a multiple image upload crud video please!
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Added this topic to the future videos, currently I have 100+ topics in that idea list so can't promise anything.
@eas7112
@eas7112 2 жыл бұрын
what is the different between action and trait ?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
See Trait examples: laravelexamples.com/tag/traits See Action example: laravelexamples.com/tag/actions
@JaimeNetoBr
@JaimeNetoBr 2 жыл бұрын
Couldn’t part of this verifications be done inside a Policy?
@LaravelDaily
@LaravelDaily 2 жыл бұрын
Yes it could, but then it would throw 403 code instead of 500. I've mentioned it in a previous video of that mini-series.
@user-ki9or2lt9r
@user-ki9or2lt9r 2 жыл бұрын
nice video, but I feel bad when I see 'else' like the one in the controller instead of early return
@Diego-eb9we
@Diego-eb9we Жыл бұрын
What about Traits? where does it fit?
@LaravelDaily
@LaravelDaily Жыл бұрын
Here are the resources about Traits, read/watch those examples: laraveldaily.com/tag/traits
@Diego-eb9we
@Diego-eb9we Жыл бұрын
@@LaravelDaily thank you so much!
@tarekadam9652
@tarekadam9652 Жыл бұрын
Action seems fine. The naming is arbitrary but logical and easy to follow. Service should probably be reserved for actual services that register and boot etc. On a side note, if you have a bunch of controller work that isn't part of the return - then you can should use jobs. (not useful here because we return $voice) If you don't have job queue infra - just use the "sync" que and your jobs will handle inline upon dispatch.
@dixonwilliam6694
@dixonwilliam6694 15 күн бұрын
where to validate the request in service?
@LaravelDaily
@LaravelDaily 15 күн бұрын
Validation should be in form request, probably
@TomHartill
@TomHartill 2 жыл бұрын
It gets to a point where your code is more instantiating different classes and calling methods than actual logic 🤣
@luizmeier
@luizmeier 2 жыл бұрын
A philosophical differente: Actions : one time class with one method, quick; Services: when there is more methods (i.e., store, update etc);
@IvanMarkovicJapy
@IvanMarkovicJapy 2 жыл бұрын
else branch should be removed in controller. Not need it
@haroldpepete
@haroldpepete 2 жыл бұрын
that refactor could be even better, service method is too long and it does a lot of thing, clean-code and solid talk about single responsability, make this code like that not allow reuse it
@javieru5871
@javieru5871 2 жыл бұрын
Controllers should be Thin & Athletic, on the contrary, Services should be Fat & Happy....
Two Things Laravel Services Should NOT Do
8:20
Laravel Daily
Рет қаралды 21 М.
Exceptions in Laravel: Why/How to Use and Create Your Own
12:18
Laravel Daily
Рет қаралды 86 М.
The child was abused by the clown#Short #Officer Rabbit #angel
00:55
兔子警官
Рет қаралды 17 МЛН
Survival skills: A great idea with duct tape #survival #lifehacks #camping
00:27
I wish I could change THIS fast! 🤣
00:33
America's Got Talent
Рет қаралды 83 МЛН
9 Tips for Shorter Laravel Code
10:16
Laravel Daily
Рет қаралды 61 М.
Laravel Model Method: Refactor into Service Class
9:05
Laravel Daily
Рет қаралды 20 М.
THIS EPIC CAN OUT NUKE MYTHICALS! ONE SHOT QUEEN!
21:33
ASH: RAID Shadow Legends
Рет қаралды 23 М.
Eloquent Observers or Events Listeners? Which is Better?
8:24
Laravel Daily
Рет қаралды 59 М.
Laravel Service Providers: All You Need to Know
13:13
Laravel Daily
Рет қаралды 63 М.
Laravel Eloquent: Deeper Relationships with One Query
10:37
Laravel Daily
Рет қаралды 137 М.
SOLID Principles in Laravel: 5 Examples (+ New Course!)
21:07
Laravel Daily
Рет қаралды 71 М.
14 Quick Laravel Tips in 9 Minutes: May 2024
9:09
Laravel Daily
Рет қаралды 9 М.
Laravel Contracts and PHP Interfaces: Explained with Two Examples
10:10
35 million watched superman video
0:13
Hasan Kaval
Рет қаралды 165 МЛН
I respect children #respect #respectshorts
0:34
Movie Copy
Рет қаралды 10 МЛН
天使和小丑连一个小朋友都比不过#short #angel #clown
0:45
Super Beauty team
Рет қаралды 12 МЛН
I respect children #respect #respectshorts
0:34
Movie Copy
Рет қаралды 10 МЛН
🔴Leo Made Daddy A Handmade M&M's🤠🤗
0:43
BorisKateFamily
Рет қаралды 6 МЛН