Laravel: Repository Pattern in practice

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good morning so today we are going to talk about the repository pattern in laravel it is a controversial Topic in the community so um hopefully you'll learn a thing or two and get to know my opinion on it so without further Ado let's get started the example that we'll be using this episode is obviously a blog post because it wouldn't be a level tutorial without a blog post so we'll have a title by the source and publish that which is notable uh I have also created a resource for it a factory a cedar and whatnot so we have the the base things that you would need to basically you know start with any any new model now let's create a simple controller that would have accrued actions for our blog post so let's do phpr system make controller blog posts controller and here we'll have our you know default index our store updates and delete should really add some automation here so I don't have to write every time uh either way now we can go to our route file and here we can simply do you know cats posts we'll return our blog post controller and then our index methods let's add the same for post put the elites and you know we also need to change the right side here so uh the corresponds and that seems to be it we'll simplify the code here and this good start so what do you do normally is uh here you would do just something like return blog post resource you know collection blog post all because we don't have users but you know we could score this by user it doesn't matter uh so yeah you would do something like this then you'd have our store you can maybe fill out like show message be Heroes Have a blog post and this would return now blog posts make uh blog post resource make a post I don't know what I'm writing to tell you about it it's definitely not code uh okay let me just fix that here we would also have a blog post and you know we would do something like uh blog posts updates data pull up data up in cycle just using them to array for now here we have a delete blog posts blog posts and you know here we would return blog posts delete here we would return blog posts create all right so first of all let me adjust this because I obviously didn't pass the blog post here look posts I will add one more for show we get posts blog posts and this would be a show method okay okay now let's make a firm request to be called blog posts request but inject it here and here blog post request and we'll need the same one here and here we'll simply password goes validated and the same will be true for up here okay uh I think we have the boilerplate done for the sake of being precise let's just field is here so it makes sense let me just copy the values from here let's just make them all required for now I also create an enum for the blog post Source uh so let's just do enormous and here we can do blog post source uh this will be an enum that will correspond to a string and here we'll have two cases one for the API and that's basically what we had in the other episode and one for the app doesn't matter now in our blog posts we'll just map it uh so our source will be mapped to blog post Source class we have to import obviously and that seems to be fine and here we just need to pass a new enum and then pass our our beautiful enum here and let's just say the state and that's all we need this is all the validation is serving uh we don't really care about this this aspect of the application I just wanted everybody to be you know up to speed with what we are doing all right so now what's great about it and what sucks about it first of all it's great because it's simple you are able to create a more or less functioning very simple but blocks in what five minutes maybe uh probably have that was me fixing the typos so this is great like we were able to be super fast the only thing we are missing is like Gates and stuff but per example it doesn't matter let's say that's another minute to our workflow who cares it's super fast now what sucks about it well not necessarily anything you could argue that uh if you were to you know create this blog post or just use it in multiple places you could end up with in duplicated codes um you could argue that the controller is not responsible or shouldn't be responsible for getting access to the database level You could argue that this application is leaky so there is no separation concerns and you can also argue that it's hard to test this in isolation so basically run tests against this code without getting x to the database you could easily does this uh in a feature test but it will be you know harder to make it to test using gaming tests so you know these are a couple of things that you should consider now me personally I rarely use repositories this is because the adults float to the code base however if you're building an Enterprise application and you're building more complex queries you want to be more strict about how data is accessed and pass through your application repositories can be really useful and if this is for you then great let me show you how to actually Implement them the pattern is data simple uh that's mostly because it's a simple PHP class the idea is to delegate all of the calls that we are making directly to eloquent to a third-party class well not First Market but a separate class that's what I meant um so what we can do in is in our app directory we could create a repository repositories folder and in here we could create a blog post Repository which you cannot see because I'm graded recording now you can blog post repository free and obviously I made the typo repositories hard work okay so we have a class this class will basically wrap our eloquent goals and on top of this what's nice is that we can create a base repository so let's do the space Repository and I made a type again okay now it's fine now the proper way of using this pattern in theory you know because we are going for the the Enterprise level is to use a lot of interfaces now this is purely optional you can use them you cannot use them if you use them this is nice because then in theory you could even swap your your repositories that access the blog posts on the Fly and uh you know you could have one blog post repository that saves it on your disk and one that saves it on the cloud drive or whatever you could do this in theory this is the the proper way to do this pattern now do you actually need it I don't think so but we are going to be decent people and we are going to create our our interfaces so let me just do the blog post I'm sorry let's start with base repository interface and let's do one more for blog posts repository interface all right okay so our base repository will implement the based repository interface and our blog post repository would extend the base repository and implement the blog post report blog post free repository interface now because this line is very long you can tell this is an Enterprise application and I'm sorry I'm just making jokes here uh so here in our basic processor you could just create a construct and here we could accept our model so our model would go here we can use the protected property and this is basically a place where you can put all of the shirt logic now in our interface you define something like public function find and here we could uh we are not going to declare their return type yet so the find method would you know accept an into our string this will depend on our application if we know that if we know it then we should just use the one if we use both we should probably use both of them here uh there's a couple of ways to approach this this doesn't matter uh let's say that our application uses paints for now and that every model using so we could so we could simply add this to our interface and now since our base repository implements the interface we just need to add the method step and the method stat would basically do return this model find ID now the big thing that we need to decide now is what will our repositories return and the most flexible way of doing this is you'll just return the model however this is not ideal because in theory um this is a leaky abstraction so this basically means that okay you are wrapping the eloquent calls in a window in those great repositories however what does it do if you can still call whatever method you want on the controller if you return and you know a model instance from here so what you would do is you would do something like this to array so this way he would return an array from our refine method uh or a null because our find could not find the method we could obviously you know do something like if there is no model then throw an exception or just do find or fail and now we could do something like this doesn't matter for our example it doesn't change that the pattern you can implement it however you want and going back to our blog post Repository you know we don't need to implement the files here anymore because it's implemented in our base repository that's how inheritance Works in case you didn't know what's the problem is that like you can't do it for a single method so for example if you define a create uh here and it accepts data right then your base Repository obviously has to comply with the interface and you do this model you know create data you'll return this then he was cast cast it to an array and you'd be good uh the problem is when you start to introduce stuff like dtos so we did talk about details in the previous episodes basically the idea is a class data transfer objects let me just create one for us really quick blog post tto will have a construct in our constructed will Define read-only public string title bring body uh blog post source and let's do carbon and then just to published at and this is nullable s something like this and we can add helper method for us that would be able to create it from request and our request here would be blog post requests and you'll simply the return new self and now you know pass the title so it's requests validated title uh let's do the same for the body the source here with the blog post source from this and for the Polish that we would do publish stats and we would simply do carbon parse and now we have our class it Returns the data and we can see the problem that our blog post repository doesn't comply with our base repository so it's not worth having it here if we want to use dtls and be really strict out what data we want to pass unless you would create a base dto and use the base dto in the base repository interface which could work but then why like it doesn't really give you all the things because base dto would wouldn't really do anything but this is an option that you could do so yeah we cannot even do it here in the base Repository so we cannot do it here in the base repository as well and we just need to create it here and at this point we just need to do you know return blog posts I'm sorry return this model create and then we can fill all the details so title title would be dto title and published it so either way let's use Xena controller so what we will do here is we would you know create a construct and here would inject a protected you think blog posts repository that in fact would inject the blog post repository interface because we want this flexibility so we can in a replace that repository if we ever need that we can easily replace that and this makes sense now this won't work out of the box what we need to do to make it work is go to app service provider in the register method we could do this up bind here we would do blog posts repository interface and bind it to blog post Repository and I'm sorry I actually made a mistake so if we go to our blog post repository I return a model what we should do here is return an array and now we are able to defer this uh eloquent call to this Repository create and my Eid doesn't understand what's going on because the interface uh doesn't have our methods and this makes sense it's a mistake that I did [Music] um we should copy the Declaration of this method and add it to our interface and this should return an array or a class just not awkward model so we could do two array or we could just you know pass it as a standard class whatever you prefer and now we just need to add the return type so going back to our controller now we are able to call this repository create and here we can pass blog post dto and this should be a public static function from request then pass the request this another thing can now be wrapped in blog post resource make so here's how you'd create a test which we need to make sure that everything is working so let's just do we need to import a test case which I didn't so now we could do something like you know this posts uh API view on posts and here we could pass the payload so we could do something like title test and China why as return you basically wants that search okay they're successful and then we can third database count on blog posts one so we obviously need to change the the current test and now we can run it and so what we should do is we should just do object and this should return an STD class and then thick sour repository to return STD class and this should solve our problem I forgot that you cannot pass a race uh three repositories like you cannot use repository make which we use here on an array unless it's a collection so this is my path I'm super sorry now to update here uh you know that it's pretty much all the same now for the update what you could do is you could pass an import ID and then the dto for delete we will just accept and enter 5D uh what else we had we had read all so it can be just called all and it will return an array and then we can also get show which will return an STD class all show create update delete I think that's all of them so first of all let us adjust our controller this repository delete blog posts ID here we'll just copy this paste it here changes from create to updates and to blog posts ID [Music] it would do this Repository show blog post ID and here we could do this Repository all and now all we need to do is Implement those methods in our blog post Repository and this you know won't be out of work here we'd simply need to return this all here we need to to turn this it should be fined not show obviously and it's actually covered in our Base Class so we don't need that here in our uh yeah let's remove show should be fine and we have fine in our base Repository we can probably move that all to base repository as well because we know this seems like something that would be reused I don't think you'd ever pretty much never call all in a real world project though but yeah on the updates we can simply do this model updates uh model update tto mute have to drag this and then paste it here let me also [Music] cast this to array should be this model all I'm making so many mistakes I'm super sorry guys let's cast this to array and this one should be casted to objects and return SD class and return STD class okay either way um this model find ID update earn top model finds we can STD class I'm sorry objects then this then to array there is a couple of other ways you could try it so it's not as bad but you know what I mean uh you'd potentially do something like you know okay let's let's do it the proper way so wallow is this right either snow model you could throw a new exception otherwise you could simply do model update ask the data ask this to array you could do something like this so it's more readable I don't know if that's actually needed but now we can just do you know turn object model to array could create a helper function called casts to objects where you could pass the model and being able let's actually do it it was her like I am pretty sure it shouldn't be the Repository uh but who cares it's our project can do private function format here we could pass the model we could simply the return object model to array this will return you know ICT class so now we could do something like you know this format it obviously shouldn't be protected uh I'm sorry it's really private should be protected and now you could you know replace this with this formats or you could just write a class that would drop it or there is a lot of things you can do and extend the base model and to other crap you can override the two array there is there is a lot of things you can do doesn't matter um so again here we could it's clear during the same pattern to this and then return model delete this was return a bully it's not compatible with our uh our declaration here so let's just change that to Bull and we should be good let's change this show here find and this is basically the the pattern if there's something that's nice to you use it you're building an Enterprise application where you cannot can't really erase a lot uh in the sense that the result of data there is a lot of complex queries there is a lot of like caching and stuff like that repositors are great for encapsulating logic especially for like you know caching stuff for accessing stuff from the third party uh you can just use them to to extend your app make it more secure can do better testing the result of benefits out of drawbacks it takes a lot of time to write all this especially if you like want to use repositories but you also want to use services so then you know your controller would call a service that would color a repository that would call your eloquent model and only then get the data so we have like this this really big this really big panel right that you have to pass all the data and responses back and forth uh but again rate pattern where it applies dot pattern or it doesn't it can easily over engineer your application in a second but if you know what you're doing go for it that's all for today thank you so much for watching and see in the next one bye
Info
Channel: Przemysław Przyłucki
Views: 10,300
Rating: undefined out of 5
Keywords: laravel, vue, tailwind, saas, laravel saas
Id: 4k1gQ2qlQvY
Channel Id: undefined
Length: 27min 13sec (1633 seconds)
Published: Wed Jan 25 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.