Laravel "app/Actions" Pattern: Useful or Over-Engineering?

Поделиться
HTML-код
  • Опубликовано: 6 июл 2024
  • Recently I've seen a few examples of app/Actions folder in Laravel projects. Let's take a look at what can be inside of it, and is it actually useful.
    Related links:
    - Freek Van der Herten: "Refactoring to actions" freek.dev/1371-refactoring-to...
    - Laravel News: "Organize Laravel Applications With Actions" laravel-news.com/organize-lar...
    - Jetstream Actions jetstream.laravel.com/2.x/con...
    - My video "Laravel Services and Repositories: 3 Example Projects": • Laravel Services and R...
    - - - - -
    Support the channel by checking out our products:
    - Try our Laravel QuickAdminPanel: bit.ly/quickadminpanel
    - Enroll in my Laravel courses: laraveldaily.teachable.com
    - Purchase my Livewire Kit: livewirekit.com
    - Subscribe to my weekly newsletter: bit.ly/laravel-newsletter
  • ХоббиХобби

Комментарии • 70

  • @ruslanvoroshchukowlookitlt245
    @ruslanvoroshchukowlookitlt245 3 года назад +7

    Superb explanation! It's easy to digest complex themes after your videos, especially great to know when to use or don't use a certain approach. Thanks for a great job Povilas, please keep posted!

  • @mohammadashrafuddinferdous9347
    @mohammadashrafuddinferdous9347 Год назад +1

    I really learn a lot from you. I can't thank you enough!
    Now, as you discussed, It all depends. I find a use case where service class is more appropriate. Suppose, I have a CreateUser action with the handle method. in the handle method, I want to keep my code more understandable and short and from a business perspective, my handle method does more things. To separate those "do more checkings and filtering" I wrote a few more methods in CreateUser action class. Not a problem!
    But if another requirement needs those same "checkings and filtering", I have multiple options.
    1. Creating traits.
    2. Write a class and consider that class as a helper class for sharable logic for DRY.
    3. Create a service class and throw most of the logic there including the handle methods logic.
    Maybe, I will go for number 3. Less class creation. But when needed I can create another class and transfer few logic there when it may be in the way of the GOD object! Helper methods are already sharable!

  • @nafiesluthfi4020
    @nafiesluthfi4020 3 года назад +3

    You are a genius content creator, Povilas.

  • @mohammadmohammadi2724
    @mohammadmohammadi2724 3 года назад +15

    Hello Laravel Daily It will be so good if you can make more videos about design patterns in Laravel with example

    • @LaravelDaily
      @LaravelDaily  3 года назад +2

      I discuss all of that in detail in my course "How to Structure Laravel Project" laraveldaily.teachable.com/p/how-to-structure-laravel-project

  • @ExpDev69
    @ExpDev69 3 года назад +23

    Personally I dislike single-action classes because the classes add up quickly. I personally prefer a service class where you have multiple actions that make sense together. Here you also get the benefit of interfaces if you want to provide multiple implementations for those actions.

    • @langstonfranco1989
      @langstonfranco1989 3 года назад

      You probably dont give a shit but if you're bored like me during the covid times then you can stream all of the new series on InstaFlixxer. I've been watching with my gf these days =)

    • @jamols09
      @jamols09 2 года назад

      Do you know where can I look for samples that I can learn from this? Im using service however I have yet to learn Actions and I wanted to mix the two together rather than single action class

  • @abdmaster
    @abdmaster 3 года назад +12

    I do similar to this, very basic and without any of those packages. Simple PHP class and i just execute it in controller, console, job or even as sub-action.

  • @musondasalimu2986
    @musondasalimu2986 3 года назад

    Wow I love how you teach, these are the things I want to learn

  • @EpicBibleShorts
    @EpicBibleShorts 3 года назад +1

    I’ve been picking up actions as of late, and like it. At it’s simplest form, just being able to navigate directly to an action vs scrolling a page is a big plus. Countless times I’ve scrolled up and down a controller because I’ve passed the action I’m looking for a couple times. Especially if I’ve added custom actions to a controller…. Also, shown right here in this video. He opened the folder to Teams and within 5 secs you knew everything you could do to the teams.

  • @mihaes7172
    @mihaes7172 2 года назад

    I appreciate your presentation and connection made among implementations based on topic.
    I notices the folder /actions because I use Innertia & stuff and looked up for reasons and landed on the same resources as you did.But
    But in the current project, I decided (still) for services.

  • @cliffordusidamen6622
    @cliffordusidamen6622 3 года назад +1

    Thanks again for this.
    In my opinion, besides that thought of slim controllers, the concept of domain-driven design (DDD)is also one of the things that are driving the 'app/Action' trend.
    It's good to understand that this is a matter of flexibility and preference if we ignore the namings used by the different 'coiners' - Actions, Jobs, Provider, Repository...

  • @rfpdl
    @rfpdl 3 года назад +2

    Good content. That is what I love with Laravel, the flexibility, great community, and the dev experience!
    You can also look at Lucid Arch, it is really good if you want to handle different services (mobile/backend/cli/etc) with reusable code. I have been using it for some of my projects, am very satisfied so far as I do not really need to think too much about where to put the code, just follow the lucid convention and get it done.

  • @Voltra_
    @Voltra_ 3 года назад

    Interesting to see that what I describe as the MVEA architectural pattern is getting around more than just MVC with Services

  • @Paltibenlaish
    @Paltibenlaish 3 года назад +1

    Great video

  • @ezp721
    @ezp721 3 года назад +4

    In this particular case, seems that those packages are not actually solving any problem, its just naming conventions. In this case I prefer to stick with what the framework (Laravel) offers natively.

  • @RichardTippin
    @RichardTippin 3 года назад

    I started using actions in an open source messenger I am currently working on. Only main difference is I made my actions chainable, and most of my actions can also return API JSON resources (Action Domain Responder pattern). Chainable because, for example, Store new message is an action that will create a new message and emit the broadcast, but within it I chain my mark participant read action, as a participant sending a message should be marked read. Flexibility wise, I have an individual route where a participant can mark a thread read as well. Actions are also great when testing as they are already quite isolated and lets me keep my HTTP tests less bloated.

  • @GergelyCsermely
    @GergelyCsermely 3 года назад

    Thanks

  • @ArjonJasonCastro
    @ArjonJasonCastro 3 года назад +1

    I use jobs because it is the most natural/native thing in laravel and you can run it anywhere and it is queueable already.
    If there are methods that pertains to the operations of a model, I put those methods on the model itself. For example:
    Post $post = Post::find($id);
    $post->publish();

  • @RahmatHidayatSlamet
    @RahmatHidayatSlamet Год назад +1

    I still have no idea why people going for action where there are built-in featute like Job.
    Job simply an action that has featute for queue, delay, sequence chain, and even so testable. It also support by artidsn command to build the skeleton and matching with laravel structure. You can also create a listener for that.

    • @RahmatHidayatSlamet
      @RahmatHidayatSlamet Год назад +1

      The best part about this is when you are going for a make a services pattern, you are not require to delete the job and move the logic to that particular service. Just make a service with similar actin name and call that job there. It's okay since the job itself is an single-purpose class that can be called anywhere.

  • @martinh4982
    @martinh4982 3 года назад +4

    I wouldn't call this over-engineering, I'd call it an anti-pattern. I'm sure it's useful - sometimes - when you're writing a framework feature, but most of us aren't doing that. I'm not surprised that Spatie was mentioned. If you asked those guys to add two numbers together they'd come up with some incomprehensible solution invoking multiple methods - all fully tested, mind you! - that no one else can make head nor tail of. This stuff is more often than not oop for the sake of opp and nothing else.

    • @chidiebere
      @chidiebere 5 месяцев назад

      🤣 what you said about spatie is really funny😂

  • @ArjonJasonCastro
    @ArjonJasonCastro 3 года назад

    For me, Taylor Otwell's actions in jetstreams is sensible because those are jetstream-specific actions, that's why interfaces there makes sense.

  • @ricko13
    @ricko13 Год назад +1

    in a nutshell: "actions" is just a fancy name for creating flexible patterns in Laravel

  • @ivan.silicin
    @ivan.silicin Год назад

    I have ar error during installation lorisleiva/laravel-actions.
    Error in composer is - Trait "Illuminate\Console\Concerns\CreatesMatchingTest" not found.
    Laravel v8.20.1

  • @nayeemdev
    @nayeemdev 3 года назад

    ❤️

  • @joejohn.
    @joejohn. 3 года назад

    Do you think actions negate the need for services, or can the two coexist? Service class calls actions in its functions or controller can call the action directly?

    • @LaravelDaily
      @LaravelDaily  3 года назад +1

      I think both can co-exist

    • @ShamilHPC
      @ShamilHPC 3 года назад

      This is what we do at work. Service layer is just an abstraction layer that calls action classes in its methods

    • @rubino9091
      @rubino9091 3 года назад

      ​@@LaravelDaily Sorry for the late response, I just got to discover your channel (and it's super educational!). I was wondering if it is also valid to approach it the other way around, as mentioned above. So that the controller calls the action, the action will contain all the logic of this controller, and then the action will call one or more services (which could call a repository if you would have a really large and complex application) to complete the 'action'.
      Or would it work better the other way around as mentioned above?
      Thanks for your comment! Cheers!

    • @olivermaglana3526
      @olivermaglana3526 2 года назад

      @@LaravelDaily is it okay to use the service class to get the value of query and do some comparison based on the result since service layer is the one handling the business logic

  • @JohnnyBigodes
    @JohnnyBigodes 3 года назад +3

    To be honest I never used actions. To take logic out of the controllers I usually use a Support folder where all my logic classes are saved. These get called on controllers and if needed I can dispatch these in a queue job.

    • @ArnelLabarda
      @ArnelLabarda 3 года назад +3

      it's the same thing as what he said just a different name.

  • @fernandoluizbortolanzza2524
    @fernandoluizbortolanzza2524 3 года назад

    Hello I'd like to suggest you make videos about how to structure folders like controllers, admins controllers for a medium to large projects. When a project is short its easy put in laravel convention but when you have many many controllers its a little confusion to organizate. Thank you

    • @LaravelDaily
      @LaravelDaily  3 года назад

      Well it's a personal preference how to organize subfolders. Not sure I can have any advice that would suit everyone here.

  • @devsnoob
    @devsnoob 4 месяца назад

    How about use repository pattern in actions ?

  • @kwameadoko9542
    @kwameadoko9542 3 года назад +2

    Jetstream's implementation of actions did actually made it clear. You can invoke an action based on a user's action. createNewUser, createNewUserWithTeam. Ok, create a new user, but this time with variations.

  • @Jurigag
    @Jurigag 3 года назад

    Why just not use messenger bus from symfony and just create commands and handlers for them? Why reinvent a wheel?

  • @RicardoVermeltfoort
    @RicardoVermeltfoort 3 года назад +1

    I don't really understand the difference between actions and jobs (at least in the first situation described by spatie)
    You could say they're synchronous jobs, but then also be queued..?
    To me that just sounds like Job::dispatchSync() and Job::dispatch() and this leads me to the confusion what "actions" are supposed to solve what jobs don't already allow you to do in the same fashion
    Edit: i do understand the case in jetstream/fortify that it allows for clear overriding of implementations that are used by a framework, so that's definitely convenient

    • @SinaSharifzade
      @SinaSharifzade 3 года назад

      They are exactly synced jobs, but when you run a job, you don't have type hintings, you have no idea what to put inside dispatch sync. this may not be a problem for smaller projects, but when the project grows, it will be a serious problem, specially if multiple developers are working on the project.

    • @RicardoVermeltfoort
      @RicardoVermeltfoort 3 года назад

      ​@@SinaSharifzade jobs can also be instantiated via the constructor using dispatch(new MyJob($arg1, $arg2)), it'd give the same type hinting, but I would agree that it is less pretty.
      But again this is something already supported by jobs and doesn't seem like something actions is giving an advantage over?
      This is what is giving me such a hard time, I can't figure out what clear advantage making custom actions provide over framework supported jobs.
      disclaimer: as said before: I do understand it in the case of Fortify/Jetstrain in the way they're doing it as they're providing a framework or library and you want to provide convenience to the user for overriding behavior, but since this video is about usage within the end application i'd also like to know a reason for that situation.
      In that case they're working with interfaces/contracts and so you can make sure your re-implementation fits said interface/contract.
      But please note, that in the case of the demonstrated package laravelactions, those behave just like the jobs (but ::run instead of ::dispatchSync) and those would also not have the type hinting as you described.

    • @SinaSharifzade
      @SinaSharifzade 3 года назад

      ​@@RicardoVermeltfoort Well those packages are not well designed. actually, Laravel itself is not well designed.
      You can use Jobs for this purpose as I did in my projects, there is no difference, both jobs and actions are meant to be 1 class, that has 1 responsibility.
      laravel.io also uses jobs.
      But jobs don't have "return type hint" also, and you don't have access to $this->dispatchNow shortcut always and you need to write the whole app(Dispatcher::class)->dis... line yourself (or perhaps use method arguments). Which is really dirty.
      Jobs are best suited for responsibilities that you don't care about the instance result, for example processing a video, you don't need a return type hint here, because you are not going to have any.

  • @stefanbogdanovic590
    @stefanbogdanovic590 3 года назад

    This is a example of CQRS, as I can see

  • @vuenice
    @vuenice Год назад

    How I personally see services as a class which can be reused in other projects.

  • @hakimfazal426
    @hakimfazal426 Год назад

    Can you review my approach .
    I want to build same endpoint for both api and web.
    1.Authentication is handle for both separately.
    2 .routes are same except login.i can also set some prefix for api.
    3.my controller .for api request we must have to set api variable.
    if(request()->header('api')){
    return GetAccounts::execute();
    }
    else
    return Inertia::render('SelectAccount/Index',(array)GetAccounts::execute()->getData());
    So now all api are available on the spots.

    • @LaravelDaily
      @LaravelDaily  Год назад +3

      I personally prefer to have totally separate controllers for API and web, to avoid such if statements.
      But it's a personal preference, do whatever is convenient for you.

    • @hakimfazal426
      @hakimfazal426 Год назад

      @@LaravelDaily ok I will then create controllers for api. thank you so much for your response.

  • @mohidden
    @mohidden 3 года назад

    nice. can you make a video about association of 3 tables or more with supplements fields .->the best way to do that. :)

    • @LaravelDaily
      @LaravelDaily  3 года назад +2

      Not sure what do you mean "3 tables with supplements fields" - can you give an exact example? And is that case happening often?

    • @mohidden
      @mohidden 3 года назад +1

      @@LaravelDaily is like pivot table but with 3 tables not 2 tables. Example . Productvariations (product_id,size_id,color_id) + title +price and qty.

    • @awmy3109
      @awmy3109 3 года назад +1

      @@mohidden Can title and price be different per variation? I think those should move to products table. Price especially.
      If the only attributes of a product are size and colour, I will just have them as columns on product_variants. If the attributes of a product are dynamic, you might need a product_attributes table and
      a pivot table: product_variant_attributes for many to many relationship between product_variants and product_attributes
      If normalization isn't required, you can just have a product_variants table with a JSON column named attributes (Containing key, value pairs)

  • @imadkhamkhami2949
    @imadkhamkhami2949 3 года назад

    How to use vue js in laravel jetstream?

    • @moauyameghari
      @moauyameghari 3 года назад

      install jetstream with inertia not livwire, it's SPA vue js

    • @mohidden
      @mohidden 3 года назад

      use inertia

  • @diegomelgar2696
    @diegomelgar2696 Год назад

    Making a controller invokable to execute just only one particular process may be something that I really loved doing but not with the Laravel Action package, it is more a design that Adam talked about to make your controllers cruddy, which you can check it out here if you haven't: ruclips.net/video/MF0jFKvS4SI/видео.html
    Nice video Povilas!

  • @gelbehexe2010
    @gelbehexe2010 3 года назад

    Sounds nice, but this pattern will not work nicely with Route::resource(...)

    • @JohnnyBigodes
      @JohnnyBigodes 3 года назад

      Why that?

    • @ExpDev69
      @ExpDev69 3 года назад

      It will. Actions do not replace your controllers, they go into your controllers

    • @mahmoudbenjabir7159
      @mahmoudbenjabir7159 3 года назад

      @@ExpDev69 he is right in case you used the package Laravel Actions instead of your controllers

    • @ExpDev69
      @ExpDev69 3 года назад

      @@mahmoudbenjabir7159 oh, gotcha. Controllers are wayyy too integrated into Laravel core to not use them. However, using them with Actions I can see use for.

    • @HussamAdil
      @HussamAdil 3 года назад

      it's has nothing to do with routing

  • @intipontt7490
    @intipontt7490 3 года назад +1

    laravel/fortify is just an overengineered mess that appeared as a result from getting too drunk on the idea of "slim controllers". Actions are, as you mentioned, just jobs to be dispatched in a synchronous fashion.

  • @vikasghai7819
    @vikasghai7819 3 года назад

    I have a question:
    I am getting 419 error when I send ajax request. I have used CSRF token, I am getting token in my headers and my data parameter. but still getting issue.
    Can anyone help?
    I have used all solutions available different platforms.