{"id":13971,"date":"2017-08-10T17:07:25","date_gmt":"2017-08-10T14:07:25","guid":{"rendered":"https:\/\/belvg.com\/blog\/?p=13971"},"modified":"2019-09-26T16:31:04","modified_gmt":"2019-09-26T14:31:04","slug":"database-in-magento-2-service-contracts","status":"publish","type":"post","link":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html","title":{"rendered":"Database in Magento 2: Service Contracts"},"content":{"rendered":"\n<p>Before you start, please check the first part: <a href=\"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html\">Database in Magento 2: Models, Resource Models, and Collections<\/a>.<\/p>\n<p>There are several important concepts that have been incorporated into Magento 2, such as plugins, dependency injection, and service contracts. These demonstrate that, overall, the changes in going from Magento 1 to Magento 2 are focused more on the way you do things &mdash;&nbsp;to be more flexible and efficient &mdash;&nbsp;rather than introducing new features.<!--more--><\/p>\n<p>Service contracts fulfill a number of important functions, such as:<\/p>\n<ul>\n<li>Improving the upgrade process<\/li>\n<li>Formalizing the customization process<\/li>\n<li>Decoupling modules<\/li>\n<\/ul>\n<p>Basically, service contracts are a set of interfaces that are available for modules to declare standard APIs. A service layer is used for making customizations without having to delve deeper into the product core. They also help with module interoperability. This is possible because the implementation of an interface might change, but the signature will not.<\/p>\n<p>Service contracts are also designed to make the customization process more formal and straightforward, helping to minimize situations where you have to hunt for classes and haphazardly make changes that might fulfill one function but break others. Magento 2 implements the &ldquo;development based on interface&rdquo; concept, in which a developer relies only on the public methods declared in an interface, not in the implementation.<br>\nIn Magento 2:<\/p>\n<ul>\n<li>Modules only communicate through the API.<\/li>\n<li>One module is not aware of the internals of another, so the implementation can change.<\/li>\n<li>Modules can be disabled or deployed on separate servers.<\/li>\n<\/ul>\n<p>Operations can be divided into two groups: <strong>data<\/strong> and <strong>operational<\/strong>.&nbsp;<strong>The data API <\/strong>provides access to a module&rsquo;s entity data. It can be found in the folder <strong><em>_MODULE_NAME_\/Api\/Data.<\/em><\/strong><\/p>\n<p><strong>The operational API<\/strong> not only provides data but also drives the actual operations used on that data. These APIs allow business operations to function properly between modules. This API usually includes the public methods of Magento 1 models and helpers.<\/p>\n<p><strong>The data API<\/strong> only exposes CRUD methods, while the <strong>operational API<\/strong> actually does something. The operational APIs for a module can be found in the folder <strong><em>MODULE_NAME_\/Api<\/em><\/strong> (except for data, which is located in a subfolder).<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_1.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"lazy alignnone size-full wp-image-13974\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_1.jpg\" alt=\"Database in Magento 2 Service Contracts_1\" width=\"811\" height=\"465\" title=\"Database in Magento 2: Service Contracts\"><\/a><\/p>\n<p>In Magento 1, when you wanted to customize a module, you had to read the core code. You had to understand how it worked, in order to be able to create the required change.<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_2.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"lazy alignnone size-full wp-image-13975\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_2.jpg\" alt=\"Database in Magento 2 Service Contracts_2\" width=\"812\" height=\"460\" title=\"Database in Magento 2: Service Contracts\"><\/a><\/p>\n<p>In Magento 2, you can now customize a module using an API interface that communicates with the model, without interacting directly with the core, a much safer approach. What are some of the benefits of using a services approach?<\/p>\n<ul>\n<li>It provides comprehensive internal documentation that allows you to make customizations without having to go into the core.<\/li>\n<li>Following this approach helps to minimize conflicts between modules.<\/li>\n<li>Magento upgrades are much safer to execute without anything breaking.<\/li>\n<li>Clear extension points make customizations easier.<\/li>\n<\/ul>\n<p>There are also some drawbacks to using a services approach, of which you should be aware.<\/p>\n<ul>\n<li>Services will often either be too simple or too complex, too broad or too granular. It will be more difficult to perform low-level, refined customizations.<\/li>\n<li>The approach may work differently with different implementations.<\/li>\n<li>It may be more difficult to debug an application using this approach.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_3.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"lazy alignnone size-full wp-image-13976\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_3.jpg\" alt=\"Database in Magento 2 Service Contracts_3\" width=\"806\" height=\"455\" title=\"Database in Magento 2: Service Contracts\"><\/a><\/p>\n<p>In this diagram, we have separated the operational API into more detailed components, specifically the business logic API and repositories. The data API and the framework API remain their own logical units. Repositories provide the equivalent of service-level collections, while the business logic API provides the actual business operations. The framework API provides interfaces, implementations, and classes for various parts.<\/p>\n<p>Here is an example of a business logic API, for the Magento catalog.<\/p>\n<pre class=\"lang:php decode:true\"><strong>namespace <\/strong>Magento\\Catalog\\Api;\r\n\/**\r\n* @api\r\n*\/\r\ninterface ProductTypeListInterface\r\n{\r\n\/**\r\n&nbsp;&nbsp;&nbsp; * Retrieve available product types\r\n&nbsp;&nbsp;&nbsp; *\r\n&nbsp;&nbsp;&nbsp; * @return \\Magento\\Catalog\\Api\\Data\\ProductTypeInterface[]\r\n&nbsp;&nbsp;&nbsp; *\/\r\n&nbsp;&nbsp; public function getProductTypes();\r\n}<\/pre>\n<p>The code below provides an example of implementing the business logic API, using the <strong><em>\\Magento\\Customer\\Api\\AccountManagementInterface<\/em><\/strong><\/p>\n<pre class=\"lang:php decode:true\">**\r\n* Authenticate a customer by username and password\r\n*\r\n* @param string $email\r\n* @param string $password\r\n* @return \\Magento\\Customer\\Api\\Data\\CustomerInterface\r\n* @throws \\Magento\\Framework\\Exception\\LocalizedException\r\n*\/\r\npublic function authenticate($email, $password);<\/pre>\n<p>To see an example for a concrete implementation, search for the public function <strong><em>\\Magento\\Customer\\Model\\AccountManagement::authenticate()<\/em><\/strong> in the app installation.<\/p>\n<p>An example of a repository interface and its implementation:<\/p>\n<pre class=\"lang:php decode:true\">\/\/INTERFACE\r\nnamespace Magento\\Catalog\\Api;\r\n\/**\r\n* @api\r\n*\/\r\ninterface ProductRepositoryInterface\r\n{\r\n&hellip;\r\nnamespace Magento\\Catalog\\Model;\r\n\/\/IMPLEMENTATION\r\nclass ProductRepository implements \\Magento\\Catalog\\Api\\ProductRepositoryInterface\r\n{\r\n...<\/pre>\n<p>One important part of the operational API is repositories. Typically, a repository is an interface that provides access to a set of objects using the<strong><em> getList()<\/em><\/strong> method. It has no obligation to extend something from Framework.<\/p>\n<div class=\"module_in_content_container\"><a href=\"https:\/\/belvg.com\/magento-webdesign\" class=\"link_to_module\" target=\"_blank\" rel=\"noopener\"><\/a><div class=\"module_content\"><img src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2019\/01\/magento-webdesign-1.png\" width=\"100\" height=\"100\" alt=\"magento webdesign\" class=\"module_image\" title=\"Database in Magento 2: Service Contracts\"><div class=\"module_content_part\"><h3 class=\"title\">Magento Webdesign<\/h3><p class=\"module_content_text\">Take your online store to the next level with BelVG Magento Webdesign<\/p><a href=\"https:\/\/belvg.com\/magento-webdesign\" class=\"link_2_to_module\" target=\"_blank\" style=\"display:inline-block\" rel=\"noopener\"><span class=\"read-more\">Visit the page<\/span><\/a><\/div><\/div><\/div>\n<p>However, repository <strong><em>getList() <\/em><\/strong>methods typically receive an instance of the <strong><em>SearchCriteriaInterface<\/em><\/strong>, defined as part of the framework. The framework also supplies an implementation for that interface, namely <strong><em>Magento\\Framework\\Api\\SearchCriteria.<\/em><\/strong><\/p>\n<p>The data API implementation may extend <strong><em>AbstractExtensibleObject<\/em><\/strong>, but it is also possible for data API implementations to extend other classes or nothing at all. Business logic API implementations usually extend nothing. Repositories usually extend nothing but expect a <strong><em>SearchCriteriaInterface<\/em><\/strong> implementation as the parameter to their <strong><em>getList() <\/em><\/strong>method.<\/p>\n<p><strong><em>AbstractSimpleObject<\/em><\/strong> is a class that is similar in concept to the Varien object in Magento 1. It also has a data property, but it does not provide magic getters and setters, it only provides protected <strong><em>_setData()<\/em><\/strong> and <strong><em>_get()<\/em><\/strong> methods, as you&rsquo;ll see in the following code example. This class is used to extend if some data needs to be configurable via di.xml. The object factory will inject the <strong><em>$data<\/em><\/strong> array as a constructor argument.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\nabstract class AbstractSimpleObject\r\n{\r\nprotected $_data;\r\npublic function __construct(array $data = [])\r\n{\r\n$this-&gt;_data = $data;\r\n}\r\nprotected function _get($key)\r\n{\r\nreturn isset($this-&gt;_data[$key]) ? $this-&gt;_data[$key] : null;\r\n}\r\npublic function setData($key, $value)\r\n{\r\n$this-&gt;_data[$key] = $value;\r\nreturn $this;\r\n}\r\npublic function __toArray()\r\n{\r\n...\r\n}\r\n}<\/pre>\n<p><strong><em>AbstractSimpleObject<\/em><\/strong> provides <strong><em>_get()<\/em><\/strong>, which returns an item from the data array, or null if the requested key doesn&rsquo;t exist. The important takeaway point is that this object does not provide public getters and setters. They need to be implemented as required by the concrete implementation extending <strong><em>AbstractSimpleObject<\/em><\/strong>.<\/p>\n<p>You extend the <strong><em>AbstractSimpleObjectBuilder<\/em><\/strong>, optionally adding methods to specify the data that is required to instantiate the simple object. Then you create an instance of your Builder and send the data to Builder. The Builder takes data and injects it into the <strong><em>SimpleObject<\/em><\/strong> when<strong><em> create()<\/em><\/strong> is called. This process reflects not having public methods.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\n\/**\r\n* Base Builder interface for simple data Objects\r\n*\/\r\ninterface SimpleBuilderInterface\r\n{\r\n\/**\r\n&nbsp;&nbsp;&nbsp; * Builds the Data Object\r\n&nbsp;&nbsp;&nbsp; *\r\n&nbsp;&nbsp;&nbsp; * @return AbstractSimpleObject\r\n&nbsp;&nbsp;&nbsp; *\/\r\n&nbsp;&nbsp; public function create();\r\n\/**\r\n&nbsp;&nbsp;&nbsp; * Return data Object data.\r\n&nbsp;&nbsp;&nbsp; *\r\n&nbsp;&nbsp;&nbsp; * @return array\r\n&nbsp;&nbsp;&nbsp; *\/\r\n&nbsp;&nbsp; public function getData();\r\n}<\/pre>\n<p><strong><em>SimpleBuilderInterface<\/em><\/strong> has two methods, <strong><em>create()<\/em><\/strong> and <strong><em>getData()<\/em><\/strong>. These are implemented mainly by the <strong><em>AbstractSimpleObjectBuilder<\/em><\/strong>.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\nabstract class AbstractSimpleObjectBuilder implements SimpleBuilderInterface\r\n{\r\n&nbsp;&nbsp; protected $data;\r\n&nbsp;&nbsp; protected $objectFactory;\r\n&nbsp;&nbsp; public function __construct(ObjectFactory $objectFactory)\r\n{\r\n$this-&gt;data = [];\r\n$this-&gt;objectFactory = $objectFactory;\r\n}\r\n&nbsp;&nbsp; public function create()\r\n{\r\n$dataObjectType = $this-&gt;_getDataObjectType();\r\n$dataObject = $this-&gt;objectFactory-&gt;create($dataObjectType, ['data' =&gt; $this-&gt;data]);\r\n$this-&gt;data = [];\r\nreturn $dataObject;\r\n}\r\n&nbsp;&nbsp; protected function _set($key, $value)\r\n{\r\n$this-&gt;data[$key] = $value;\r\nreturn $this;\r\n}\r\n&nbsp;&nbsp; protected function _getDataObjectType()\r\n{\r\n$currentClass = get_class($this);\r\n$builderSuffix = 'Builder';\r\n$dataObjectType = substr($currentClass, 0, -strlen($builderSuffix));\r\nreturn $dataObjectType;\r\n}\r\n&nbsp;&nbsp; public function getData()\r\n{\r\nreturn $this-&gt;data;\r\n}\r\n}<\/pre>\n<p>Within the <strong><em>AbstractSimpleObjectBuilder::create()<\/em><\/strong> method, the data array is passed to the object factory to be injected into the <strong><em>$dataObject<\/em><\/strong> during instantiation. You can see from the code of the method <strong><em>_getDataObjectType()<\/em><\/strong> that the simple object type is the class name of the builder without the word &ldquo;builder&rdquo; attached at the end.<\/p>\n<div class=\"content_sales_info\" style=\"background-image: url(https:\/\/belvg.com\/blog\/wp-content\/uploads\/2019\/03\/Sales_background.png\"><img width=\"65\" height=\"65\" src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2015\/11\/Andrey_Dubina.png\" alt=\"Andrey_Dubina\" title=\"Database in Magento 2: Service Contracts\"><div class=\"content_part\"><h3 class=\"title\">Partner With Us <\/h3><span class=\"sales_content_text\">Let's discuss how to grow your business. Get a Free Quote.<\/span><\/div> <a class=\"call-to-action\" href=\"https:\/\/belvg.com\/contact?utm_source=blog&amp;utm_campaign=sales_block&amp;utm_content=middle\" target=\"_blank\" rel=\"noopener\">Talk to Andrey<\/a><\/div>\n<p>Repositories provide access to data sources, acting as a type of intermediary.<\/p>\n<p>The advantage to using this design pattern and its service API is that your application can function independently of the number of data sources and how they are connected to the app. This allows for easier upgrades, and since repositories deal with data objects and not models, the structure is compatible with any Object Relational Mapping system. So, for example, if you were to expand the product line of a store, in theory, you could add data sources without having to modify the application itself. Only the repository would have to know about the new sources.<\/p>\n<table width=\"0\">\n<tbody>\n<tr>\n<td width=\"281\">Repository<\/td>\n<td width=\"312\">Collection<\/td>\n<\/tr>\n<tr>\n<td width=\"281\">As Service, will remain unchanged with new releases<\/td>\n<td width=\"312\">Might be changed, or totally replaced with different mechanism in new releases<\/td>\n<\/tr>\n<tr>\n<td width=\"281\">Deals with Data Objects<\/td>\n<td width=\"312\">Returns, a list of Magento Models<\/td>\n<\/tr>\n<tr>\n<td width=\"281\">Provides high-level access to the data<\/td>\n<td width=\"312\">Provides low-level access to the data<\/td>\n<\/tr>\n<tr>\n<td width=\"281\">Support SearchCriteria mechanism for filtering and sorting<\/td>\n<td width=\"312\">Provides the own interface for most of the database operations. Highly customizable.<\/td>\n<\/tr>\n<tr>\n<td width=\"281\">Does not provide low-level access to the database<\/td>\n<td width=\"312\">Provides an access to the select object, gives an ability to create custom queries<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre class=\"lang:php decode:true\">namespace Magento\\Customer\\Api;\r\n\/**\r\n* Customer CRUD interface.\r\n* @api\r\n*\/\r\ninterface CustomerRepositoryInterface\r\n{\r\n&nbsp;&nbsp; public function save(\\Magento\\Customer\\Api\\Data\\CustomerInterface $customer, $passwordHash = null);\r\n&nbsp;&nbsp; public function get($email, $websiteId = null);\r\n&nbsp;&nbsp; public function getById($customerId);\r\n&nbsp;&nbsp; public function getList(\\Magento\\Framework\\Api\\SearchCriteriaInterface $searchCriteria);\r\n&nbsp;&nbsp; public function delete(\\Magento\\Customer\\Api\\Data\\CustomerInterface $customer);\r\n&nbsp;&nbsp; public function deleteById($customerId);\r\n}<\/pre>\n<p>Here is a code example of a repository &mdash;&nbsp;the <strong><em>CustomerRepositoryInterface<\/em><\/strong>. As you can see, the customer repository interface is composed of a number of public methods which all deal with the persistence layer. The parameters are <strong><em>Magento\\Customer\\Model\\Data\\Customer<\/em><\/strong> instances, not to be confused with regular customer models, <strong><em>Magento\\Customer\\Model\\Customer<\/em><\/strong>.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Customer\\Model\\ResourceModel;\r\nclass CustomerRepository implements \\Magento\\Customer\\Api\\CustomerRepositoryInterface\r\n{\r\n&hellip;\r\npublic function get($email, $websiteId = null)\r\n{\r\n$customerModel = $this-&gt;customerRegistry-&gt;retrieveByEmail($email, $websiteId);\r\nreturn $customerModel-&gt;getDataModel();\r\n}\r\npublic function getById($customerId)\r\n{\r\n$customerModel = $this-&gt;customerRegistry-&gt;retrieve($customerId);\r\nreturn $customerModel-&gt;getDataModel();\r\n}\r\n&hellip;\r\n}<\/pre>\n<p>In looking at the <strong><em>get()<\/em><\/strong> function, you will notice the customer registry (<strong><em>$this-&gt;customerRegistry<\/em><\/strong>) object.<\/p>\n<p>In contrast to one large registry in Magento 1, Magento 2 has a number of smaller registries. If you call <strong><em>get()<\/em><\/strong> with the same arguments two times, it will return the same instance. This is an example of the identity map design pattern.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Customer\\Model;\r\nclass CustomerRegistry\r\n{\r\n&hellip;\r\npublic function retrieve($customerId)\r\n{\r\n&nbsp;&nbsp; if (isset($this-&gt;customerRegistryById[$customerId])) {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $this-&gt;customerRegistryById[$customerId];\r\n&nbsp;&nbsp; }\r\n&nbsp;&nbsp; \/** @var Customer $customer *\/\r\n&nbsp;&nbsp; $customer = $this-&gt;customerFactory-&gt;create()-&gt;load($customerId);\r\n&nbsp;&nbsp; if (!$customer-&gt;getId()) {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ customer does not exist\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw NoSuchEntityException::singleField('customerId', $customerId);\r\n&nbsp;&nbsp; } else {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $emailKey = $this-&gt;getEmailKey($customer-&gt;getEmail(), $customer-&gt;getWebsiteId());\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;customerRegistryById[$customerId] = $customer;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;customerRegistryByEmail[$emailKey] = $customer;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $customer;\r\n&nbsp;&nbsp; }\r\n}<\/pre>\n<p>Here you see that the registry uses the <strong><em>$customerId<\/em><\/strong> to check if the requested customer model already was loaded. If not, the injected <strong><em>customerFactory<\/em><\/strong> is used to create a customer model instance, which then is loaded. The fully loaded model is then placed in the registry properties <strong><em>customerRegistryById<\/em><\/strong> and <strong><em>customerRegistryByEmail<\/em><\/strong>. On subsequent calls, the customer already will be known to the registry and will be returned directly.<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_4.png\"><img decoding=\"async\" loading=\"lazy\" class=\"lazy alignnone size-full wp-image-13978\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_4.png\" alt=\"Database in Magento 2 Service Contracts_4\" width=\"2500\" height=\"1932\" title=\"Database in Magento 2: Service Contracts\"><\/a><\/p>\n<p>SearchCriteria is the parameter in a repository&rsquo;s <strong><em>getList()<\/em><\/strong> method, which defines filters, sorting, and paging.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Customer\\Model;\r\nclass GroupManagement implements \\Magento\\Customer\\Api\\GroupManagementInterface\r\n{\r\n&hellip;\r\npublic function getLoggedInGroups()\r\n{\r\n$notLoggedInFilter[] = $this-&gt;filterBuilder\r\n-&gt;setField(GroupInterface::ID)\r\n-&gt;setConditionType('neq')\r\n-&gt;setValue(self::NOT_LOGGED_IN_ID)\r\n-&gt;create();\r\n$groupAll[] = $this-&gt;filterBuilder\r\n-&gt;setField(GroupInterface::ID)\r\n-&gt;setConditionType('neq')\r\n-&gt;setValue(self::CUST_GROUP_ALL)\r\n-&gt;create();\r\n$searchCriteria = $this-&gt;searchCriteriaBuilder\r\n-&gt;addFilters($notLoggedInFilter)\r\n-&gt;addFilters($groupAll)\r\n-&gt;create();\r\nreturn $this-&gt;groupRepository-&gt;getList($searchCriteria)-&gt;getItems();\r\n}\r\n&hellip;\r\n}<\/pre>\n<p>Looking at the code above, you can see how the search criteria instance is created, using <strong><em>SearchCriteriaBuilder<\/em><\/strong>. First, all filters are added to the builder, and then the <strong><em>SearchCriteria<\/em><\/strong> object is instantiated using the builder&rsquo;s <strong><em>create()<\/em><\/strong> method.<\/p>\n<p><strong><em>SearchCriteria<\/em><\/strong> implements the <strong><em>SearchCriteriaInterface<\/em><\/strong> and extends the class <strong><em>AbstractSimpleObject<\/em><\/strong>. It uses the set of filters contained within <strong><em>Search\\FilterGroup<\/em><\/strong>, which in turn wraps <strong><em>Filter<\/em><\/strong> instances. <strong><em>SearchCriteriaBuilder<\/em><\/strong>, extending <strong><em>AbstractSimpleObject<\/em><\/strong>, is used to create the <strong><em>SearchCriteria<\/em><\/strong> object.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\ninterface SearchCriteriaInterface\r\n{\r\n&nbsp;&nbsp; public function getFilterGroups();\r\n&nbsp;&nbsp; public function setFilterGroups(array $filterGroups = null);\r\n&nbsp;&nbsp; public function getSortOrders();\r\n&nbsp;&nbsp; public function setSortOrders(array $sortOrders = null);\r\n&nbsp;&nbsp; public function getPageSize();\r\n&nbsp;&nbsp; public function setPageSize($pageSize);\r\n&nbsp;&nbsp; public function getCurrentPage();\r\n&nbsp;&nbsp; public function setCurrentPage($currentPage);\r\n}<\/pre>\n<p>Here is a list of the public methods available within the <strong><em>SearchCriteriaInterface<\/em><\/strong>. Please note that usually the manipulators for the <strong><em>SearchCriteria<\/em><\/strong> are not used. According to best practices, all properties should be set on the <strong><em>SearchCriteriaBuilder<\/em><\/strong>, which in turn injects the complete <strong><em>$data<\/em><\/strong> array during instantiation. Once the <strong><em>SearchCriteria<\/em><\/strong> has been instantiated in this way, only getters should be used on it.<\/p>\n<p>The Filter class extends <strong><em>AbstractSimpleObject<\/em><\/strong> and adds the methods <strong><em>get\/setField()<\/em><\/strong>, <strong><em>get\/setValue()<\/em><\/strong>, and <strong><em>get\/setConditionType()<\/em><\/strong>. Just as with <strong><em>SearchCriteria<\/em><\/strong>, even though the class exposes setters, it will usually be constructed using the <strong><em>FilterBuilder<\/em><\/strong>, which injects all values during instantiation.<\/p>\n<p>SearchResult:<\/p>\n<ul>\n<li>Implement methods listed in <strong><em>SearchResultInterface<\/em><\/strong><\/li>\n<li>Is implemented by <strong><em>Magento\\Framework\\Api\\SearchResult<\/em><\/strong><\/li>\n<li>Extends <strong><em>AbsractSimpleObject<\/em><\/strong><\/li>\n<\/ul>\n<p>As its name implies, <strong><em>SearchResults<\/em><\/strong> is an object that represents search results. It is the base interface returned from repository <strong><em>getList()<\/em><\/strong> methods.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\ninterface SearchResultsInterface\r\n{\r\n&nbsp;&nbsp; public function getItems();\r\n&nbsp;&nbsp; public function setItems(array $items);\r\n&nbsp;&nbsp; public function getSearchCriteria();\r\n&nbsp;&nbsp; public function setSearchCriteria(\\Magento\\Framework\\Api\\SearchCriteriaInterface $searchCriteria);\r\n&nbsp;&nbsp; public function getTotalCount();\r\n&nbsp;&nbsp; public function setTotalCount($totalCount);\r\n}<\/pre>\n<p>This code example lists the public methods of the <strong><em>SearchResultsInterface<\/em><\/strong>.<\/p>\n<p><strong>Business logic:<\/strong><\/p>\n<ul>\n<li>Implements business features<\/li>\n<li>Does not connect to any generic framework<\/li>\n<\/ul>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_5.png\"><img decoding=\"async\" loading=\"lazy\" class=\"lazy alignnone size-full wp-image-13980\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_5.png\" alt=\"Database in Magento 2 Service Contracts_5\" width=\"1760\" height=\"1360\" title=\"Database in Magento 2: Service Contracts\"><\/a><\/p>\n<p>This overview diagram illustrates how the elements that compose the theoretical API relate to a module. The business logic API contains all the logic not contained within repositories or the data API, and is responsible basically for all the actions a module can take. In the business logic part of a module, you have unique features such as sending an email, selecting a product, and placing an order.<\/p>\n<h2>Data API<\/h2>\n<p>Data objects are essentially a set of fields defined by an interface that allow us to describe the type of data to use. The data API defines the getters and setters for each of these fields. Secondly, we need some flexibility, to define new attributes, provide information about relations, and so on. The data API is designed to meet this need by allowing the assignment of custom attributes. This may seem somewhat of a contradiction: We want the API to offer flexibility, yet we also want it to provide a well-defined structure for interacting with services like SOAP. We will examine both aspects in this module.<\/p>\n<table width=\"0\">\n<tbody>\n<tr>\n<td width=\"282\">Customer Module Implementation<\/td>\n<td width=\"311\">Catalog Module Implementation<\/td>\n<\/tr>\n<tr>\n<td width=\"282\">Data interfaces implemented in separate classes<\/td>\n<td width=\"311\">Data interfaces implemented by models<\/td>\n<\/tr>\n<tr>\n<td width=\"282\">All service-layer works with data interfaces<\/td>\n<td width=\"311\">Service-layer only works with models<\/td>\n<\/tr>\n<tr>\n<td width=\"282\">When customizing developer should care about both &ndash; models and data models<\/td>\n<td width=\"311\">Developer should only care about models<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>How do you implement the data API? We already know that there is a data API folder containing interfaces that describe the data objects used by the service API. There are two possible ways to implement the interfaces. One is to create dedicated data objects &mdash; objects that solely contain data and have no behavior beyond getters and setters. This is outlined in the customer module column of the table.<\/p>\n<p>The second approach is to operate with regular models that additionally implement the getters\/setters defined in the data API interface, besides containing their business logic. This is outlined in the catalog module column of the table. The recommended way to work with Magento 2 is to have dedicated data objects that implement data API interfaces. Basically, both approaches operate with data API interfaces. In the first (customer) case, if you call the customer module API, it will return instances of classes that only implement the data interface. Alternatively, if you call the catalog module API, it will return instances of regular models that also implement the data API interface.<\/p>\n<p>So, in general, you should rely only on the interface methods, as the implementation may vary or be changed in future releases. Look at the methods within the interface, and restrict yourself to using only those. Do not rely on, for example, a model save() method, as that may change in future releases and break your system. This is why Magento 2 introduced service layers and API interfaces, to make upgrades safer.<\/p>\n<pre class=\"lang:php decode:true \">namespace Magento\\Customer\\Model\\ResourceModel;\r\nclass CustomerRepository implements \\Magento\\Customer\\Api\\CustomerRepositoryInterface\r\n{\r\n&hellip;\r\npublic function getList(SearchCriteriaInterface $searchCriteria)\r\n{\r\n&hellip;\r\n$collection-&gt;setCurPage($searchCriteria-&gt;getCurrentPage());\r\n   $collection-&gt;setPageSize($searchCriteria-&gt;getPageSize());\r\n   $customers = [];\r\n   \/** @var \\Magento\\Customer\\Model\\Customer $customerModel *\/\r\n   foreach ($collection as $customerModel) {\r\n       $customers[] = $customerModel-&gt;getDataModel();\r\n   }\r\n   $searchResults-&gt;setItems($customers);\r\n   return $searchResults;\r\n}\r\n&hellip;\r\n}\r\n<\/pre>\n<p>The <strong><em>CustomerRepository<\/em><\/strong> is an example of the implementation of data objects.<\/p>\n<pre class=\"lang:php decode:true \">namespace Magento\\Catalog\\Model;\r\nclass ProductRepository implements \\Magento\\Catalog\\Api\\ProductRepositoryInterface\r\n{\r\n&hellip;\r\npublic function getList(\\Magento\\Framework\\Api\\SearchCriteriaInterface $searchCriteria)\r\n{\r\n&hellip;\r\n$collection-&gt;load();\r\n\r\n   $searchResult = $this-&gt;searchResultsFactory-&gt;create();\r\n   $searchResult-&gt;setSearchCriteria($searchCriteria);\r\n   $searchResult-&gt;setItems($collection-&gt;getItems());\r\n   $searchResult-&gt;setTotalCount($collection-&gt;getSize());\r\n   return $searchResult;\r\n}\r\n&hellip;\r\n}\r\n<\/pre>\n<p>In the <strong><em>ProductRepository<\/em><\/strong> example, you see that the service layer API directly returns the product models. Both approaches generally use <strong><em>$searchResult<\/em><\/strong> interface.<\/p>\n<div class=\"module_in_content_container\"><a href=\"https:\/\/belvg.com\/magento-custom-development\" class=\"link_to_module\" target=\"_blank\" rel=\"noopener\"><\/a><div class=\"module_content\"><img src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2019\/01\/magento-custom-development.png\" width=\"120\" height=\"120\" alt=\"magento custom development\" class=\"module_image\" title=\"Database in Magento 2: Service Contracts\"><div class=\"module_content_part\"><h3 class=\"title\">Magento Custom Development<\/h3><p class=\"module_content_text\">Take your online store to the next level with BelVG Magento Custom Development <\/p><a href=\"https:\/\/belvg.com\/magento-custom-development\" class=\"link_2_to_module\" target=\"_blank\" style=\"display:inline-block\" rel=\"noopener\"><span class=\"read-more\">Visit the page<\/span><\/a><\/div><\/div><\/div>\n<h2>Extensible Object<\/h2>\n<p>Unlike API services, which can be arbitrary, the data API situation is different because the metadata of the data is the same; so, its representation is the same. Every interface extends a special interface, <strong><em>ExtensibleDataInterface<\/em><\/strong>. The concrete implementation implements the interface but most also extend <strong><em>AbstractExtensibleObject<\/em><\/strong>. This object has a couple of very important methods: <strong><em>get\/setExtensionAttributes()<\/em><\/strong>. These methods return the extension object, which is used to customize objects. Your data goes into the extension object. The <strong><em>AbstractExtensibleObject<\/em><\/strong> implementation includes sets of attributes (standard, custom, and extension) and extends the <strong><em>AbstractExtensibleObject<\/em><\/strong>.<\/p>\n<p>This object extends ExtensibleDataInterface using two factories: <strong><em>ExtensionAttributeFactory<\/em><\/strong> and <strong><em>AttributeValueFactory<\/em><\/strong>. <strong><em>AbstractExtensibleObject<\/em><\/strong> also implements <strong><em>CustomAttributeDataInterface<\/em><\/strong>, which in turn extends <strong><em>ExtensibleDataInterface<\/em><\/strong>.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\ninterface ExtensibleDataInterface\r\n{\r\n\/**\r\n&nbsp;&nbsp;&nbsp; * Key for extension attributes object\r\n&nbsp;&nbsp;&nbsp; *\/\r\n&nbsp;&nbsp; const EXTENSION_ATTRIBUTES_KEY = 'extension_attributes';\r\n}<\/pre>\n<p>The <strong><em>ExtensibleDataInterface<\/em><\/strong> only contains a constant used as the data array key for an extension_attributes object.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\ninterface CustomAttributesDataInterface extends ExtensibleDataInterface\r\n{\r\n&nbsp;&nbsp; const CUSTOM_ATTRIBUTES = 'custom_attributes';\r\n\/**\r\n&nbsp;&nbsp;&nbsp; * Get an attribute value.\r\n&nbsp;&nbsp;&nbsp; *\r\n&nbsp;&nbsp;&nbsp; * @param string $attributeCode\r\n&nbsp;&nbsp;&nbsp; * @return \\Magento\\Framework\\Api\\AttributeInterface|null\r\n&nbsp;&nbsp;&nbsp; *\/\r\n&nbsp;&nbsp; public function getCustomAttribute($attributeCode);\r\n&nbsp;&nbsp; public function setCustomAttribute($attributeCode, $attributeValue);\r\n&nbsp;&nbsp; public function getCustomAttributes();\r\n&nbsp;&nbsp; public function setCustomAttributes(array $attributes);\r\n}<\/pre>\n<p>The <strong><em>CustomDataInterface<\/em><\/strong> also contains a key. This one is for custom attributes.<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_6.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"lazy alignnone size-full wp-image-13981\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts_6.jpg\" alt=\"Database in Magento 2 Service Contracts_6\" width=\"807\" height=\"458\" title=\"Database in Magento 2: Service Contracts\"><\/a><\/p>\n<p>This diagram provides more detail on the ExtensibleObject diagram, three slides earlier.<\/p>\n<p><strong><em>AbstractExtensibleObject<\/em><\/strong> will take a parameter of <strong><em>ExtensionAttributesFactory<\/em><\/strong> or <strong><em>AttributeValueFactory<\/em><\/strong> via dependency injection. When you create an implementation of that interface, it extends its own extensible object with its own custom logic. If you want to have some objects in your method, you would have to use or alter a constructor. This all gets a little more complex when you add an interface to the model.<\/p>\n<p>So instead, specify the custom attributes using the getters and setters defined in the <strong><em>AbstractExtensibleObject<\/em><\/strong>. You set custom attributes using the <strong><em>AttributeValueFactory()<\/em><\/strong>, which provides an <strong><em>AttributeInterface<\/em><\/strong>. Then, with this interface, you can set the code and the values you want. Every EAV interface implementation will have its own metadata object. The metadata object is an analog of the EAV config class in Magento 1, which provided information on attributes, classes, entities, and more.<\/p>\n<pre class=\"lang:php decode:true\">namespace Magento\\Framework\\Api;\r\nuse \\Magento\\Framework\\Api\\AttributeValueFactory;\r\nabstract class AbstractExtensibleObject extends AbstractSimpleObject implements CustomAttributesDataInterface\r\n{\r\n&hellip;\r\nprotected function _getExtensionAttributes()\r\n{\r\nreturn $this-&gt;_get(self::EXTENSION_ATTRIBUTES_KEY);\r\n}\r\nprotected function _setExtensionAttributes(\\Magento\\Framework\\Api\\ExtensionAttributesInterface $extensionAttributes)\r\n{\r\n$this-&gt;_data[self::EXTENSION_ATTRIBUTES_KEY] = $extensionAttributes;\r\nreturn $this;\r\n}\r\n...\r\n}<\/pre>\n<p>The code here demonstrates how to set an extension attributes object.<\/p>\n<div class=\"module_in_content_container\"><a href=\"https:\/\/belvg.com\/magento-support\" class=\"link_to_module\" target=\"_blank\" rel=\"noopener\"><\/a><div class=\"module_content\"><img src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/07\/Magento_support.png\" width=\"120\" height=\"120\" alt=\"Magento support\" class=\"module_image\" title=\"Database in Magento 2: Service Contracts\"><div class=\"module_content_part\"><h3 class=\"title\">Magento Support<\/h3><p class=\"module_content_text\">Take your online store to the next level with BelVG Magento Support<\/p><a href=\"https:\/\/belvg.com\/magento-support\" class=\"link_2_to_module\" target=\"_blank\" style=\"display:inline-block\" rel=\"noopener\"><span class=\"read-more\">Visit the page<\/span><\/a><\/div><\/div><\/div>\n\n","protected":false},"excerpt":{"rendered":"Before you start, please check the first part: Database in Magento 2: Models, Resource Models, &#8230;","protected":false},"author":58,"featured_media":13983,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_acf_changed":false,"footnotes":""},"categories":[35,14,389,524],"tags":[],"class_list":["post-13971","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-certification","category-magento","category-magento2-development","category-magento-speed-optimization","post_format-post-format-image"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"Here is the second part of our great article dedicated to Database in Magento. Today we are going to talk about Service Contracts.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Aleksander Kutseika\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#article\",\"name\":\"Database in Magento 2: Service Contracts | BelVG Blog\",\"headline\":\"Database in Magento 2: Service Contracts\",\"author\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/aleksander-kutseika#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/08\\\/Database-in-Magento-2-Service-Contracts.jpg\",\"width\":770,\"height\":290,\"caption\":\"Database in Magento 2 Service Contracts\"},\"datePublished\":\"2017-08-10T17:07:25+02:00\",\"dateModified\":\"2019-09-26T16:31:04+02:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#webpage\"},\"articleSection\":\"Certification, Magento, Magento 2 Development, Magento Speed Optimization, Image\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/belvg.com\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento#listItem\",\"name\":\"Magento\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento#listItem\",\"position\":2,\"name\":\"Magento\",\"item\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#listItem\",\"name\":\"Database in Magento 2: Service Contracts\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#listItem\",\"position\":3,\"name\":\"Database in Magento 2: Service Contracts\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento#listItem\",\"name\":\"Magento\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#organization\",\"name\":\"BelVG Blog\",\"description\":\"Magento and Prestashop articles\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/aleksander-kutseika#author\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/aleksander-kutseika\",\"name\":\"Aleksander Kutseika\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/20dcba617ca05952a14d36e3f30fc6a632094549decebf7a03ba790095042cd3?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Aleksander Kutseika\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#webpage\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html\",\"name\":\"Database in Magento 2: Service Contracts | BelVG Blog\",\"description\":\"Here is the second part of our great article dedicated to Database in Magento. Today we are going to talk about Service Contracts.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/aleksander-kutseika#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/aleksander-kutseika#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/08\\\/Database-in-Magento-2-Service-Contracts.jpg\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html\\\/#mainImage\",\"width\":770,\"height\":290,\"caption\":\"Database in Magento 2 Service Contracts\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-service-contracts.html#mainImage\"},\"datePublished\":\"2017-08-10T17:07:25+02:00\",\"dateModified\":\"2019-09-26T16:31:04+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/\",\"name\":\"BelVG Blog\",\"description\":\"Magento and Prestashop articles\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Database in Magento 2: Service Contracts | BelVG Blog","description":"Here is the second part of our great article dedicated to Database in Magento. Today we are going to talk about Service Contracts.","canonical_url":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#article","name":"Database in Magento 2: Service Contracts | BelVG Blog","headline":"Database in Magento 2: Service Contracts","author":{"@id":"https:\/\/belvg.com\/blog\/author\/aleksander-kutseika#author"},"publisher":{"@id":"https:\/\/belvg.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts.jpg","width":770,"height":290,"caption":"Database in Magento 2 Service Contracts"},"datePublished":"2017-08-10T17:07:25+02:00","dateModified":"2019-09-26T16:31:04+02:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#webpage"},"isPartOf":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#webpage"},"articleSection":"Certification, Magento, Magento 2 Development, Magento Speed Optimization, Image"},{"@type":"BreadcrumbList","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/belvg.com\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/category\/magento#listItem","name":"Magento"}},{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/category\/magento#listItem","position":2,"name":"Magento","item":"https:\/\/belvg.com\/blog\/category\/magento","nextItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#listItem","name":"Database in Magento 2: Service Contracts"},"previousItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#listItem","position":3,"name":"Database in Magento 2: Service Contracts","previousItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/category\/magento#listItem","name":"Magento"}}]},{"@type":"Organization","@id":"https:\/\/belvg.com\/blog\/#organization","name":"BelVG Blog","description":"Magento and Prestashop articles","url":"https:\/\/belvg.com\/blog\/"},{"@type":"Person","@id":"https:\/\/belvg.com\/blog\/author\/aleksander-kutseika#author","url":"https:\/\/belvg.com\/blog\/author\/aleksander-kutseika","name":"Aleksander Kutseika","image":{"@type":"ImageObject","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/20dcba617ca05952a14d36e3f30fc6a632094549decebf7a03ba790095042cd3?s=96&d=mm&r=g","width":96,"height":96,"caption":"Aleksander Kutseika"}},{"@type":"WebPage","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#webpage","url":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html","name":"Database in Magento 2: Service Contracts | BelVG Blog","description":"Here is the second part of our great article dedicated to Database in Magento. Today we are going to talk about Service Contracts.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/belvg.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#breadcrumblist"},"author":{"@id":"https:\/\/belvg.com\/blog\/author\/aleksander-kutseika#author"},"creator":{"@id":"https:\/\/belvg.com\/blog\/author\/aleksander-kutseika#author"},"image":{"@type":"ImageObject","url":"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/08\/Database-in-Magento-2-Service-Contracts.jpg","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html\/#mainImage","width":770,"height":290,"caption":"Database in Magento 2 Service Contracts"},"primaryImageOfPage":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html#mainImage"},"datePublished":"2017-08-10T17:07:25+02:00","dateModified":"2019-09-26T16:31:04+02:00"},{"@type":"WebSite","@id":"https:\/\/belvg.com\/blog\/#website","url":"https:\/\/belvg.com\/blog\/","name":"BelVG Blog","description":"Magento and Prestashop articles","inLanguage":"en-US","publisher":{"@id":"https:\/\/belvg.com\/blog\/#organization"}}]}},"aioseo_meta_data":{"post_id":"13971","title":"Database in Magento 2: Service Contracts | #site_title","description":"Here is the second part of our great article dedicated to Database in Magento. Today we are going to talk about Service Contracts.","keywords":null,"keyphrases":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":null,"twitter_description":null,"schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-11-03 18:37:16","updated":"2026-11-03 18:37:16"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/belvg.com\/blog\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/belvg.com\/blog\/category\/magento\" title=\"Magento\">Magento<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tDatabase in Magento 2: Service Contracts\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/belvg.com\/blog\/"},{"label":"Magento","link":"https:\/\/belvg.com\/blog\/category\/magento"},{"label":"Database in Magento 2: Service Contracts","link":"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html"}],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts\/13971","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/users\/58"}],"replies":[{"embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/comments?post=13971"}],"version-history":[{"count":3,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts\/13971\/revisions"}],"predecessor-version":[{"id":23830,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts\/13971\/revisions\/23830"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/media\/13983"}],"wp:attachment":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/media?parent=13971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/categories?post=13971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/tags?post=13971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}