Refactoring real-world Laravel app. Who wrote THIS CODE?!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good morning everybody so I I decided that today we are going to do something that's quite different uh so as you may know I have a poster shop and uh let's just say the code isn't ideal so I decided that today we could kind of dive in into a real project and just work on refining the code base so let's just jump right into this all righty so just so you have some context this is the the bespoke project so here he doesn't have a lot of data but like you know it's a landing page it has some some data uh it's cool because like you can generate posters on the Fly and like you have some that are in a pretty fine and you also have like these these galleries so we can get inspired maybe uh build your own wall but that's still important what we are interested in here is the code base I have like a bunch of controllers here that are kind of Mac you know we were kind of rushing to just get this out of the way and um and get the project done so the code is not ideal it's also like not super bad we just need to make it a bit better so this is what we are going to to focus on now you know I obviously got like resources but uh the controls are not purely created so it contains only the the Productions so you know index store update deletes and stuff like that uh the results of like logic in the controller so maybe we can simply sprinkle some service Logic on top of it and make sure that the code is scalable for the future normally I would follow like domain driven design but for now we can just start with services so I'll just create a new directory called services and here we'll put some some Logic for our controllers so first of all we need to think that we really want to have all of the controllers in one directory and the answer is probably almost always no because you know it's the project grows we are going to have a bunch of controllers here so maybe let's create folders for them so first let's select them by like the resource that they're connected to so maybe we can start with user so the user controller and user order controller would go there these are order control is actually kind of controversial maybe it's connected to user to order more than a user but I think so I think it's gonna help the user doesn't matter um let's go further and you know two one for coupon so we can put our coupon validate controller here uh we can create one for gallery the color controller here and now let's do one for newsletter and you know this is a bunch of this is just me creating a bunch of folders so this must be super entertaining so I will try and make it as quick as possible let's create one for contacts one for category one for the payment 140 order and one for the product see you get the gist of its just split everything into folders right and with the magic of PHP storm our apis got refactored so like all the uses of these Converse were also refactored so they are telling the proper way so this is perfect uh now what we need to do is we just need to make sure that every single one of those converters is better than it's currently and you know we can't we didn't have to make it perfect we can just do a couple of iterations right so maybe let's start with services or whatever comes to mind so let's look at the user so here we can see a couple of problems right first of all this is like super ugly and this is an easy fix what we can do is we can actually go into this this request and here we can do a public function called validated and we can just override default or we can do like a custom function called user data it's whatever uh since last versions level kind of extended the default validated method so it has key and and defaults this makes it kind of tricky because you should follow the standard but in theory like in theory you should follow Center but I never do it so maybe just let's go with user data and user data will simply get this validated so this will return a full data that passes the evaluation and then we can do simply something like data password equals hash make data passwords and now we can just return the data so this will obviously return an array and now here what we can do is we can simply do in a request user update and then just passed uh request user data so this is a simple fix now let's see if our password is card that it's not we can now obviously remove those commands because we all know what it does now here we can see an index that just Returns the user data what would be more preferable is to return a resource containing the user data so maybe we can create this resource so we already have a user resource and this is used nowhere actually so that's pretty cool we'll just steal that and use it here so we can simply do user resource make request user and here it will return a user resource so yeah I'm pretty sure this is all of the data that we need here so you know this is not perfect but it's definitely better uh here we could create a research but honestly I think it's an Overkill at this point now let's go to user order controller and here we can see it's kind of you know what maybe let's create that that user service so in our services we'll create a new directory called user and here we'll create a user service user service okay let's just use here we'll just use a construct and then we'll do protected user service this thing I always forget to change my PHP settings PHP storm settings so it goes like this but just do it manually and here we could do something like you know Service uh this service orders for uh leased orders and we can simply pass the request user we'll copy this and here we'll pass the request so you see the pilmate HTTP request and now we need to create this methods and this would simply return something like this and now we need to replace this with user ID and this will return a collection and the eloken collection this is fine but what we also can do is we can see if the user has relationship with orders and he doesn't so let's just add it a link function orders and the user as many there okay so now in our service what we can do is we can simply do user orders latest kit and this just reads better okay so maybe let's go to our newsletter controller and this should be fairly simple what we are going to do here is uh we are simply going to create a new a new service so let's create a new slider and here you can simply add a new slider service here you know let's just initiate it and you slap your series and all we need to do is do this service subscribe and then we just need to pass the email or just to recall deleted emails so we don't have an inline variable and then we can copy all of the scrap it's here this will be a string called email and that's fine and here we can do this service unsubscribe and let's just pass the email all right so that's pretty straightforward uh now let's go to Galleries and here okay now we have a bit more happening so first of all let's think about this we have the sitemap here and I love it so maybe we can create something called Gallery sitemap controller and I will simply replace the the Callback here from this function to just the gallery sitemap controller and here we'll have an invokable controller and for now let's just copy this uh the body of this method all right so you know the drill now let's just create a directory let's do gallery and let's see how the gallery service okay so here we can basically see that we are caching our response here so we don't have to duplicate this query it's not super expensive query but but why would we duplicate it if you know it will be the same all the time the more important question is where does the cash live and you can argue that it leaves in the controller or in the service in this specific example I I will just utilize it and just create the method in service that indicates that the resource that we are fetching is cached so here we can just do service get all uh obviously this service and this will return an anonymous resource collection uh okay so here how do we call it lease all right now get all get old Okay so let's name it get all cached and let's just paste it here and you know now we are good so these two could be merged together uh there is this new edition called with where has and this basically just changed where it has with um so we can just utilize that so maybe instead of even doing that we can just create a scope called valid or theologists divide and in our gallery we can do public function scope valid because we are only adding a one scope there is no reason to just like create a separate query cluster like that this simple project there's no need to over engineer that so let's pause the Builder and we'll just do you know Builder with Warehouse products I'm not a fan of the valid because like maybe available [Music] I think that reads better uh because it's not like the other galleries are invalid they're just you know being created so maybe available is a better term and here we should have a semicolon instead of the coma and this will return a collection um all right so this seems fine now for now we didn't really do anything novel it's just me moving stuff around but maybe we'll get to something you never know I'm just you know trying to show you the process it's not always exciting sometimes you just do these small improvements and just get something new at the end so let's just go through controllers let's just have some fun uh you know pop a soda or whatever and so yeah here you know we don't need that strength lower it was previously in the enum so that's why I left it here uh second of all let's create a request here so I will just do PHP what'd they do I open thinker boxes uh let's do PHP Ortiz and make requests and here we can simply do coupon validate request and let's import that and here we can remove all of this crap and we'll just do you know coupon required exists coupon code so now you won't be able to you know submit a coupon that doesn't work uh that they create Scouts coupons codes okay so now we can just replace it with first or fail all right and now I think we're in a good spot to let's just replace get we validated uh we are in a good spot to create the service so let's just create a directory called coupon here we can create a coupon service now we'll just create the construct here you know the drill I'll just acted coupon service and this can be replaced with a resource you know what I just prefer to copy that's rid of that just copy the user resource make it a coupon resource okay we have an ID we don't need an ID we can just copy these things here and I'll just replace it all with this and now we can simply do coupon resource make coupon you don't have yet let's say coupon will be this service validate coupon and now let's just pass that coupon and let's create that method it will accept a string of coupon and here we can do this we'll create a new exception let's call it coupon exception so the coupon exception would extend the uh base exception and here we could create two static functions so one would be not found this would simply return new static uh I will just write it out in Polish because this is a Polish website and I just I want to convey that message to the user to just return a static and now uh we'll create another one for invalid which will just show new static okay and this will return the 403 and again the original type is static uh so a cool thing that we could do is we could actually create like an custom exception and this would be an abstract class that would extend the exception and this class could implement the cast extend the custom exception uh all right so now we can utilize it here so we can simply Grow coupon exception invalid and let's just replace it to find and if there is no requested coupon we can throw coupon exception not found and you may wonder why did we create this custom exception class I will show you in a second um we'll just replace this with coupon helps okay let's this will be coupon codes this will be first not find and this will be coupon and this will return that coupon okay so now back to our controller back to our controller we did create this custom exception simply because now here what we can do is we can catch custom exception and we know that those are the exceptions rates intentionally by our application so we can simply return in a response Json with message of exception get message and here we can do exception get code you can also write a custom exception Handler that would do it for us but for now we'll just keep it here so it's more readable and everybody knows what's happening and this will obviously return a coupon resource till now the contact form this is a beautiful um little male that's I honestly don't care about this is not going to change like ever so who cares now our category controller this is again super simple but the category is like an important Concept in the app and I think it will grow and grow so let's just be preemptive about this and create a new category so let's just create category service and this will simply let's create a service and we'll call it get all and let's create a public function construct and here we can do protected category service alrighty now let's add this get all methods that will return this and let's split this into multiple lines so it's more readable you dial a query Builder to simplify this or whatever but honestly super simple let's just leave it as it is now looking at the admin controller you know it's definitely not ideal but it's admin it's like more or less whatever we can do and what I think is worth is we'll create a new class called you know admin order download controller and admin order Ed controller and these two bad boys are simply going to take care of these two methods that weren't supposed to be in that controller and let's make them invokable let's paste it here and now we can make it invokable as well and we just need to change the Declaration in our API so let's go to apa.php and here we just need to replace these two with admin order shift controller hence admin order download controller all right so I think the last thing that we kinda didn't do is the payment controller and this one is signed so don't even think about posting web hooks to this URL you're not going to win with me uh but yeah we just need to make sure that this one is also in a working con and has nice code so we can start with doing a request so we can do PHP and make requests uh payments payment web hook requests let's do payments web hook request and since this is a structured formats we don't really need to add rules because we know what you're going to get but we can just do something that you know order is required and then order dots external order ID is also required and when it comes to payments you know we can make a service for sure because there is some additional logic that I do not want to share in the order controller um just to be on the safe side to to not expose anything that's sensitive but uh here we can Services we can do new anyways and let's create the payment controller I'm sorry the payment service and here we'll just do public function uh consume callback and we'll simply defer to that all right so here we can do public payment service and simply do this service consume and here we can do Quest all and this will accept data this will get data let's rename the data to order maybe not order but what's the data if there are the response types isn't completed we can just return and otherwise we'll just mark this page and I have no clue why is it's called handle let's just do payment controller and here we'll just invoke all right so honestly it's not a lot like we just went through a couple of controllers and made them slightly better but honestly this is all this job is about so like this was the refactoring in the 80 20 rule right we made it slightly better did we do everything correctly no but it's a code better yes is it better maintainable yes so that's all that counts see in the next one a great week bye
Info
Channel: Przemysław Przyłucki
Views: 3,604
Rating: undefined out of 5
Keywords: laravel, vue, tailwind, saas, laravel saas
Id: lSRuFPbxXn0
Channel Id: undefined
Length: 28min 2sec (1682 seconds)
Published: Mon Feb 06 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.