PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Service Contracts – Data Interfaces and Repository Pattern in Magento 2

by Henryk Tews / Tuesday, 12 February 2019 / Published in Magento 2

Directly using Magento 2 models in your own code is a tempting shortcut. The model is right there, it has the method you need, it works. The problem appears when Magento is updated and the internal implementation changes. Service Contracts are Magento’s answer – a stable, public API separated from the implementation.

What are Service Contracts?

A Service Contract is a set of PHP interfaces defining the public API of a module. Magento splits them into two types:

  • Data Interfaces – describe data structures (e.g. ProductInterface, OrderInterface)
  • Service Interfaces – describe business operations (e.g. ProductRepositoryInterface)

Interfaces annotated with @api are covered by Magento’s backward-compatibility guarantee.

Model vs Repository – a concrete example

<?php

// The "shortcut" way - direct model usage
class MyClass
{
    public function getProduct(int $id): \Magento\Catalog\Model\Product
    {
        $product = $this->productFactory->create();
        $product->load($id); // load() deprecated since Magento 2.1!
        return $product;
    }
}
<?php

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Api\Data\ProductInterface;

class MyClass
{
    public function __construct(
        private ProductRepositoryInterface $productRepository
    ) {}

    public function getProduct(int $id): ProductInterface
    {
        return $this->productRepository->getById($id);
    }
}

Data Interfaces – SearchCriteria example

<?php

class ProductService
{
    public function __construct(
        private ProductRepositoryInterface $productRepository,
        private SearchCriteriaBuilder $searchCriteriaBuilder
    ) {}

    public function getActiveProducts(): array
    {
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter('status', 1)
            ->addFilter('visibility', [2, 3, 4], 'in')
            ->setPageSize(20)
            ->create();

        $result = $this->productRepository->getList($searchCriteria);

        return array_map(
            fn(ProductInterface $p) => [
                'sku'   => $p->getSku(),
                'name'  => $p->getName(),
                'price' => $p->getPrice(),
            ],
            $result->getItems()
        );
    }
}

Defining your own Service Contracts

<?php

namespace Vendor\Module\Api\Data;

/**
 * @api
 */
interface SubscriptionInterface
{
    public function getId(): ?int;
    public function getEmail(): string;
    public function setEmail(string $email): self;
    public function getCreatedAt(): string;
}
<!-- di.xml - bind interface to implementation -->
<preference for="Vendor\Module\Api\Data\SubscriptionInterface"
            type="Vendor\Module\Model\Subscription"/>
<preference for="Vendor\Module\Api\SubscriptionRepositoryInterface"
            type="Vendor\Module\Model\SubscriptionRepository"/>

Summary

Service Contracts are real protection against problems during Magento upgrades. Code based on @api interfaces is more resilient to internal platform changes and easier to test – you can replace the repository implementation with a mock without changing the calling code.

About Henryk Tews

What you can read next

Xdebug – configuration, PHPStorm, debugging Magento plugins
Strategy pattern in PHP – and how Magento 2 uses it in pricing

© 2026 Created by

TOP
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Always active
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
Zobacz preferencje
  • {title}
  • {title}
  • {title}