Laravel API Resource: Loading relationship the right way

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey there sam suppose we're building an app and our database looks something like this we have a company model and one company can have many users and one user can have many posts and now let's try to build our api so here i have a fresh laravel installation and i have set up a few files in advance i've defined the relationship in the user model and also the company model and created the api controller files using the laravel make command i've also added the api routes for companies and users and also some dummy data in my database alright let's get started by creating the resource class for company and user we'll go to terminal php artisan make resource company resource and also user results that will take care of the volatility for us now let's go to the company resource class i want the api response to return the company id and also all the related users inside the company since we have already defined the user relationship in a company model we can just load the users right away and to keep the api response consistent we should wrap our users in the user resource class by the collection method so far so good now let's also do the user resource class for the user i also want the api to return the id and also the user's company data and similar to the company resource i can just type it new company resource this company right i'll give you one second to think about this time's up the answer is hell no why because in our user resource class here we are loading the company relationship in the company resource class and in the company resource class we're loading a user's relationship in the user resource class which will then load the company resource class again and on and on and on can you see how this could bring us a massive disaster and this is definitely not the right way to load api relationship so what options do we have well we could ditch the resource class completely and load the relationship directly right that's an option but we can no longer guarantee our api will be consistent as your app grows larger and larger it becomes increasingly difficult to control what goes out from your app and that's why we need this resource class to help us manage our outgoing data not using this resource class is just another path leads to disaster so hell no so what's the better option then the answer is eager loading if you're not familiar with the terms here's a brief overview there are three different ways to load a model relationship in laravel the first way is called lazy loading which is the default way to load the relationship just like we did in our app at here so lazy loading means to load the relationship on demand the relationship will remain as a placeholder until it's actually being used the second way is called eager loading which simply means to load the relationship at a time when a query was executed so the relationship will always be there regardless whether the data is being used or not the third way is called lazy eager loading this is a scenario where we load the relationship eagerly after the query was executed let's go through them one by one and see how can they solve our problem here let's go to company controller and the index method will load companies with users eagerly loaded we can do that by using the width method from the model the width method accepts an array of relationships as defined in the company model and eloquent will load these relationships eagerly when the query is executed then we'll return to company using the company resource class calling the collection method and pass in the paginated companies so now all the companies pass into the company resource class would have users eagerly loaded with them let's go back to our company resource class and now we need to fix how we load our users and again by default laravel loads the relationship lazily and we need to stop doing that we can call the when loaded method on the model to only load the relationship when it has already been eagerly loaded so if the company does not have users eagerly loaded the user's fields will be omitted completely what's the benefit of doing this you'll see that in a minute this is where we start breaking the infinite loop now let's go to our user resource class we'll create a new variable company is equal to this well loaded company so here we're basically saying that we only retrieve the company relationship when the current user model has eagerly loaded company in other words if the user model passed on to this resource class does not have company eager loaded the company variable here will be empty and this is exactly where we break the infinite loop let's walk through everything once again first we start at the company controller we first retrieve our companies with users eager loaded then we pass them into the company resource class and in the company resource class we will retrieve the users loaded and pass them on to the user resource class a very important note here is that the user relationship loaded here they do not have company eager loaded with them so that means in the user resource class our company variable here will be empty and if company is empty and therefore it will not trigger the relationship loading in the company resource class which is equal to breaking the infinite loop so now that means we can safely pass this company variable to our company resource class down there let's run php addition serve and we'll test our api in the browser and we get a beautifully formatted json response without any infinite relationship loading and just a note if we have nested relationship we can use a dot notation in the width method for example just for demonstration purposes let's go back to company controller if i want to load the company again for each user i can put dot company right after users let's go back to the browser again and now each user will have a company attached to them this example probably wouldn't make sense it'll be better if we change company to post which we haven't implemented yet i'll leave that as an exercise for you now there's one more thing i want to talk about before we end the lesson for the show method since laravel has already resolved the model for us we no longer need to construct a query and therefore won't have access to the width method so instead of using width we can call the load missing function from the model directly it works like the method width but it's only callable on the model instance so we are essentially eager loading the user relationship after the company model has been resolved this is also known as lazy eager loading let's try this out we first need to add a show route then we go to the browser and view company id1 and that's it key takeaway for this lesson eager loading means loading the relationship at the time when a query was executed we use the width method on queries to perform eager loading lazy loading is a default way that laravel handles relationship loading it loads the relationship on demand and the relationship will remain as a placeholder until it's actually being used lazy eager loading loads a relationship eagerly after the query was executed we use a load missing method to perform lazy eager loading eager loading can help us to break the infinite loop when we load relationship in our resource class that's it for this lesson and i'll see you again shortly if you enjoy the content of this video don't forget to hit the like subscribe and the bell icon for more content to come it will really help me out thanks for the support [Music] you
Info
Channel: Acadea.io
Views: 14,074
Rating: undefined out of 5
Keywords: laravel, api, web development, eager loading, eloquent
Id: __DyyzHgYGg
Channel Id: undefined
Length: 7min 24sec (444 seconds)
Published: Thu Aug 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.