Resource models do not hold data but responsible for storing and retrieving operations to the DB.
Which means you can not say:
//Not allowed in resource model
//Not allowed in resource model
But you should get and set data to the Model object. Then tell Resource Model to save the model. Like:
As per design pattern, no entity should be responsible for it’s own load and delete. So, these two methods of a model has made deprecated in Magento.
Rather than the model itself, corresponding Resource model should be responsible for these functionality.
We can achieve that functionality in many ways. One of them can be,
First take the Resource Mode object and then pass the model and the id of the entity to the load or delete method of the Resource Model.
Repository class lives in the same directory of model. With the name
Repository holds common actions of the data like, save, getById, getList, delete, deleteById
Repository’s getList method is highly dependent on SearchCriteria.This blog post has a very good example of Repository Pattern with SearchCriteria: https://medium.com/@dannynimmo/how-to-use-the-repository-pattern-in-magento-2-4914caa67eaa
There is Model and Resource model, why another Repository?
As per design pattern, model can only store non persistent data. It should not be responsible for operations on persistent data, resourceModel does that.
Repository does not know where the data is coming from. The data source can be file system or the cache or the DB.
You can say, this is another layer of accessing the data.
Well, why another layer?
Magento 2 was heavily refactored from M1 to make it more API friendly. The headless PWA is one of the outcomes of this refactoring.
The primary purpose of an API is that, the one who is consuming the API does not know the complexity of the system. Whatever or how the data will be served, consumer does not care.
They just need data.
Repository is part of the Magento 2 API system. In M2 architectural convention, when some API endpoint is called, we don’t execute any controller or block.
We bind the API endpoint with a method of a Repository interface. That Repository Interface resides in “Api” folder of that module.
Later in “di.xml” file, we define the preferred class of that Repository interface through a “preference” tag.
Definitely, we will not write the same business logic twice. So, the Repository class is not limited to the API only. We can use that class anywhere we need the data.
How do we use the Repository in our system?
Repository classes should implement the service contractor of
<Model>RepositoyInterface and start using it.
What really is a Service Contract ?
This is nothing but another fancy term of software engineering.
Actually, this is an interface. Which declares all the required methods.
Again, the API consumers do not know what is inside my system. They only know what I am providing them. Now, how do I tell them what I am providing? One way can be making a documentation and provide that to the consumer. Well that it too manual solution and that does not solve many things. Like, what are the method parameters, how can I force the consumer the data types of the parameters, as REST API will actually communicate with plain texts or JSON you can say. But no way to say the Object type.
In M2, with the help of Interface’s php doc block’s parameter definition, Magento ensures the data data type.
In the system, when we are forcing the developer to implement the Interface, we actually are forcing developers to implement those methods that were defined in the interface, so, the consumers will never miss the exposed API methods / endpoints.
Another minor benefits of this design pattern is, tools like Swagger can automatically create API documentation and some access functionality by ready the codes only.
Here we are providing some services from our system to some consumers. To do that, both parties are maintaining some set of rules which we can call signing a contract. And that contract is nothing but that Interface.That is why we are calling that interface a “Service Contract”