Magento 2 Best Practices – When to Use Repository and Factory

best practicefactorymagento2repository

I have gone through a couple of tutorials in Magento 2, and this confuses me a little. I can see there are basically two ways by which we can read/write business entities:

Retrieve Data

Using A Factory Approach

$object = $this->myFactory->create();
$object->load($myId);

Using A Repository Approach

$repo   = $this->myRepository();
$object = $repo->getById($myId);

Save Data

Using A Factory Approach

$object = $this->myFactory->create();
$object->load($myId);
$object->setData('something', 'somethingDifferent')->save();

Using A Repository Approach

$repo   = $this->myRepository();
$object = $repo->getById($myId);
$object->setData('something', 'somethingDifferent');
$repo->save($object);

I can also see that, both a repository and a factory class can be injected using dependency injection. This is confusing at least for me.

When should we use a repository approach and a factory approach? What is the best practice we need to follow?

Best Answer

If there is a repository and it does what you need well, always prefer the repository.

Repositories are part of the Service Contracts (they are implementations of interfaces in Api), this means they are meant as a public interface to other modules.

Use Repositories for full loading

$model->load() is not part of the service contract. I had a question on that particular topic, you might find the answers useful: Is there ever a reason to prefer $model->load() over service contracts?

Use Factories to create new entities

Repositories do not come with methods to create a new entity, so in that case, you will need a factory. But use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.

Then use the repository->save() method to save it.

Use Collection Factories if you need more control

The following is not official Magento best practice, but currently, repositories do not give you fine control over what to load. The search criteria API lets you define filters, but for example, there is no way to select particular EAV attributes or specify which index tables to join.

These are implementation details, hidden from the service contract APIs, but often these implementation details matter and you get poor performance if you ignore them. For that reason, as soon as the repositories are limiting me I don't hesitate anymore to use the underlying collections.

Related Topic