Ich begrüße Sie, liebe Habraviten! Da ich seit 2013 auf der Magento-E-Commerce-Plattform entwickle, Mut gesammelt habe und der Überzeugung bin, dass ich mich in diesem Bereich zumindest als selbstbewusster Entwickler bezeichnen kann, habe ich beschlossen, meinen ersten Artikel über dieses System auf dem Hub zu schreiben. Und ich werde mit der Implementierung der REST-API in Magento 2 beginnen. Hier gibt es sofort Funktionen für die Verarbeitung von Anforderungen, und ich werde versuchen, dies anhand eines Beispiels eines einfachen Moduls zu demonstrieren. Dieser Artikel ist eher für diejenigen gedacht, die bereits mit Magenta gearbeitet haben. Und so, wer interessiert ist, bitte unter der Katze.
Krawatte
Meine Vorstellungskraft ist sehr schlecht, daher habe ich folgendes Beispiel gefunden: Stellen Sie sich vor, wir müssen ein Blog implementieren, nur Benutzer aus dem Admin-Bereich können Artikel schreiben. Von Zeit zu Zeit klopft ein CRM an uns und lädt diese Artikel zu sich selbst hoch (warum es nicht klar ist, aber so werden wir die Verwendung der REST-API rechtfertigen). Um das Modul zu vereinfachen, habe ich ausdrücklich auf die Implementierung der Anzeige von Artikeln im Frontend und im Admin-Bereich verzichtet (Sie können es selbst implementieren, ich empfehle einen guten
Artikel zu Grids). Hier ist nur die Abfrageverarbeitungsfunktion betroffen.
Aktionsentwicklung
Erstellen Sie zunächst die
Struktur des Moduls und nennen Sie es
AlexPoletaev_Blog (der Mangel an Vorstellungskraft ist nicht verschwunden). Wir platzieren das Modul im
App / Code- Verzeichnis.
AlexPoletaev / Blog / etc / module.xml<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="AlexPoletaev_Blog" setup_version="1.0.0"/> </config>
AlexPoletaev / Blog / registration.php <?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'AlexPoletaev_Blog', __DIR__ );
Diese beiden Dateien sind das für das Modul erforderliche Minimum.
Wenn alles in Feng Shui erledigt ist, müssen wir Serviceverträge erstellen (was es in Magenta gibt und wie es funktioniert, können Sie
hier und
hier lesen), was wir tun werden:
AlexPoletaev / Blog / Api / Data / PostInterface.php <?php namespace AlexPoletaev\Blog\Api\Data; interface PostInterface { const ID = 'id'; const AUTHOR_ID = 'author_id'; const TITLE = 'title'; const CONTENT = 'content'; const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; public function getId(); public function setId($id); public function getAuthorId(); public function setAuthorId($authorId); public function getTitle(); public function setTitle(string $title); public function getContent(); public function setContent(string $content); public function getCreatedAt(); public function setCreatedAt(string $createdAt); public function getUpdatedAt(); public function setUpdatedAt(string $updatedAt); }
AlexPoletaev / Blog / Api / PostRepositoryInterface.php <?php namespace AlexPoletaev\Blog\Api; use AlexPoletaev\Blog\Api\Data\PostInterface; use Magento\Framework\Api\SearchCriteriaInterface; interface PostRepositoryInterface { public function get(int $id); public function getList(SearchCriteriaInterface $searchCriteria); public function save(PostInterface $post); public function delete(PostInterface $post); public function deleteById(int $id); }
Lassen Sie uns diese beiden Schnittstellen genauer analysieren. Die
PostInterface- Oberfläche zeigt eine Tabelle mit Artikeln aus unserem Blog an. Erstellen Sie unten eine Tabelle. Jede Spalte aus der Datenbank muss einen eigenen Getter und Setter in dieser Schnittstelle haben. Wir werden später herausfinden, warum dies wichtig ist. Die
PostRepositoryInterface- Schnittstelle bietet eine Reihe von Standardmethoden für die Interaktion mit der Datenbank und das Speichern geladener Entitäten im Cache. Die gleichen Methoden werden für die API verwendet. Ein weiterer wichtiger Hinweis ist das Vorhandensein korrekter PHPDocs in diesen Schnittstellen, da Magenta bei der Verarbeitung einer REST-Anforderung Reflexion verwendet, um die Eingabeparameter und Rückgabewerte in den Methoden zu bestimmen.
Erstellen Sie mithilfe des
Installationsskripts eine Tabelle, in der Beiträge aus dem Blog gespeichert werden:
AlexPoletaev / Blog / Setup / InstallSchema.php <?php namespace AlexPoletaev\Blog\Setup; use AlexPoletaev\Blog\Api\Data\PostInterface; use AlexPoletaev\Blog\Model\ResourceModel\Post as PostResource; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Ddl\Table; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Security\Setup\InstallSchema as SecurityInstallSchema; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); $table = $setup->getConnection() ->newTable( $setup->getTable(PostResource::TABLE_NAME) ) ->addColumn( PostInterface::ID, Table::TYPE_INTEGER, null, ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], 'Post ID' ) ->addColumn( PostInterface::AUTHOR_ID, Table::TYPE_INTEGER, null, ['unsigned' => true, 'nullable' => true,], 'Author ID' ) ->addColumn( PostInterface::TITLE, Table::TYPE_TEXT, 255, [], 'Title' ) ->addColumn( PostInterface::CONTENT, Table::TYPE_TEXT, null, [], 'Content' ) ->addColumn( 'created_at', Table::TYPE_TIMESTAMP, null, ['nullable' => false, 'default' => Table::TIMESTAMP_INIT], 'Creation Time' ) ->addColumn( 'updated_at', Table::TYPE_TIMESTAMP, null, ['nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE], 'Update Time' ) ->addForeignKey( $setup->getFkName( PostResource::TABLE_NAME, PostInterface::AUTHOR_ID, SecurityInstallSchema::ADMIN_USER_DB_TABLE_NAME, 'user_id' ), PostInterface::AUTHOR_ID, $setup->getTable(SecurityInstallSchema::ADMIN_USER_DB_TABLE_NAME), 'user_id', Table::ACTION_SET_NULL ) ->addIndex( $setup->getIdxName( PostResource::TABLE_NAME, [PostInterface::AUTHOR_ID], AdapterInterface::INDEX_TYPE_INDEX ), [PostInterface::AUTHOR_ID], ['type' => AdapterInterface::INDEX_TYPE_INDEX] ) ->setComment('Posts') ; $setup->getConnection()->createTable($table); $setup->endSetup(); } }
Die Tabelle enthält die folgenden Spalten (nicht vergessen, wir haben alles so einfach wie möglich):
- id - automatische Inkrementierung
- author_id - admin-Benutzerkennung (Fremdschlüssel im Feld user_id aus der Tabelle admin_user)
- Titel - Titel
- Inhalt - Artikeltext
- created_at - Erstellungsdatum
- update_at - Bearbeitungsdatum
Jetzt müssen Sie einen Standardsatz von Magenta
Model- ,
ResourceModel- und
Collection- Klassen erstellen. Warum ich diese Klassen nicht male, ist dieses Thema umfangreich und geht über den Rahmen dieses Artikels hinaus. Interessierte können selbst googeln. Kurz gesagt, diese Klassen werden zum Bearbeiten von Entitäten (Artikeln) aus der Datenbank benötigt. Ich empfehle Ihnen, sich über die Muster des Domänenmodells, des Repositorys und der Serviceschicht zu informieren.
AlexPoletaev / Blog / Model / Post.php <?php namespace AlexPoletaev\Blog\Model; use AlexPoletaev\Blog\Api\Data\PostInterface; use AlexPoletaev\Blog\Model\ResourceModel\Post as PostResource; use Magento\Framework\Model\AbstractModel; class Post extends AbstractModel implements PostInterface { protected $_idFieldName = PostInterface::ID;
AlexPoletaev / Blog / Model / ResourceModel / Post.php <?php namespace AlexPoletaev\Blog\Model\ResourceModel; use AlexPoletaev\Blog\Api\Data\PostInterface; use Magento\Framework\Model\ResourceModel\Db\AbstractDb; class Post extends AbstractDb { const TABLE_NAME = 'alex_poletaev_blog_post'; protected function _construct() //@codingStandardsIgnoreLine { $this->_init(self::TABLE_NAME, PostInterface::ID); } }
AlexPoletaev / Blog / Model / ResourceModel / Post / Collection.php <?php namespace AlexPoletaev\Blog\Model\ResourceModel\Post; use AlexPoletaev\Blog\Model\Post; use AlexPoletaev\Blog\Model\ResourceModel\Post as PostResource; use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; class Collection extends AbstractCollection { protected function _construct() //@codingStandardsIgnoreLine { $this->_init(Post::class, PostResource::class); } }
Ein aufmerksamer Leser wird feststellen, dass unser Modell die zuvor erstellte Schnittstelle und alle ihre Getter und Setter implementiert.
Gleichzeitig implementieren wir das Repository und seine Methoden:
AlexPoletaev / Blog / Model / PostRepository.php <?php namespace AlexPoletaev\Blog\Model; use AlexPoletaev\Blog\Api\Data\PostInterface; use AlexPoletaev\Blog\Api\Data\PostSearchResultInterface; use AlexPoletaev\Blog\Api\Data\PostSearchResultInterfaceFactory; use AlexPoletaev\Blog\Api\PostRepositoryInterface; use AlexPoletaev\Blog\Model\ResourceModel\Post as PostResource; use AlexPoletaev\Blog\Model\ResourceModel\Post\Collection as PostCollection; use AlexPoletaev\Blog\Model\ResourceModel\Post\CollectionFactory as PostCollectionFactory; use AlexPoletaev\Blog\Model\PostFactory; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; class PostRepository implements PostRepositoryInterface { private $registry = []; private $postResource; private $postFactory; private $postCollectionFactory; private $postSearchResultFactory; public function __construct( PostResource $postResource, PostFactory $postFactory, PostCollectionFactory $postCollectionFactory, PostSearchResultInterfaceFactory $postSearchResultFactory ) { $this->postResource = $postResource; $this->postFactory = $postFactory; $this->postCollectionFactory = $postCollectionFactory; $this->postSearchResultFactory = $postSearchResultFactory; } public function get(int $id) { if (!array_key_exists($id, $this->registry)) { $post = $this->postFactory->create(); $this->postResource->load($post, $id); if (!$post->getId()) { throw new NoSuchEntityException(__('Requested post does not exist')); } $this->registry[$id] = $post; } return $this->registry[$id]; } public function getList(SearchCriteriaInterface $searchCriteria) { $collection = $this->postCollectionFactory->create(); foreach ($searchCriteria->getFilterGroups() as $filterGroup) { foreach ($filterGroup->getFilters() as $filter) { $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); } } $searchResult = $this->postSearchResultFactory->create(); $searchResult->setSearchCriteria($searchCriteria); $searchResult->setItems($collection->getItems()); $searchResult->setTotalCount($collection->getSize()); return $searchResult; } public function save(PostInterface $post) { try { $this->postResource->save($post); $this->registry[$post->getId()] = $this->get($post->getId()); } catch (\Exception $exception) { throw new StateException(__('Unable to save post #%1', $post->getId())); } return $this->registry[$post->getId()]; } public function delete(PostInterface $post) { try { $this->postResource->delete($post); unset($this->registry[$post->getId()]); } catch (\Exception $e) { throw new StateException(__('Unable to remove post #%1', $post->getId())); } return true; } public function deleteById(int $id) { return $this->delete($this->get($id)); } }
Die Methode
\AlexPoletaev\Blog\Model\PostRepository::getList()
sollte Daten eines bestimmten Formats zurückgeben, daher benötigen wir auch diese Schnittstelle:
AlexPoletaev / Blog / Api / Data / PostSearchResultInterface.php <?php namespace AlexPoletaev\Blog\Api\Data; use Magento\Framework\Api\SearchResultsInterface; interface PostSearchResultInterface extends SearchResultsInterface { public function getItems(); public function setItems(array $items); }
Um das Testen unseres Moduls zu vereinfachen, erstellen wir zwei Konsolenskripte, mit denen Testdaten hinzugefügt und aus der Tabelle entfernt werden:
AlexPoletaev / Blog / Console / Command / DeploySampleDataCommand.php <?php namespace AlexPoletaev\Blog\Console\Command; use AlexPoletaev\Blog\Api\PostRepositoryInterface; use AlexPoletaev\Blog\Model\Post; use AlexPoletaev\Blog\Model\PostFactory; use Magento\User\Api\Data\UserInterface; use Magento\User\Model\User; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class DeploySampleDataCommand extends Command { const ARGUMENT_USERNAME = 'username'; const ARGUMENT_NUMBER_OF_RECORDS = 'number_of_records'; private $postFactory; private $postRepository; private $user; public function __construct( PostFactory $postFactory, PostRepositoryInterface $postRepository, UserInterface $user ) { parent::__construct(); $this->postFactory = $postFactory; $this->postRepository = $postRepository; $this->user = $user; } protected function configure() { $this->setName('alex_poletaev:blog:deploy_sample_data') ->setDescription('Blog: deploy sample data') ->setDefinition([ new InputArgument( self::ARGUMENT_USERNAME, InputArgument::REQUIRED, 'Username' ), new InputArgument( self::ARGUMENT_NUMBER_OF_RECORDS, InputArgument::OPTIONAL, 'Number of test records' ), ]) ; parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output) { $username = $input->getArgument(self::ARGUMENT_USERNAME); $user = $this->user->loadByUsername($username); if (!$user->getId() && $output->getVerbosity() > 1) { $output->writeln('<error>User is not found</error>'); return null; } $records = $input->getArgument(self::ARGUMENT_NUMBER_OF_RECORDS) ?: 3; for ($i = 1; $i <= (int)$records; $i++) { $post = $this->postFactory->create(); $post->setAuthorId($user->getId()); $post->setTitle('test title ' . $i); $post->setContent('test content ' . $i); $this->postRepository->save($post); if ($output->getVerbosity() > 1) { $output->writeln('<info>Post with the ID #' . $post->getId() . ' has been created.</info>'); } } } }
AlexPoletaev / Blog / Console / Command / RemoveSampleDataCommand.php <?php namespace AlexPoletaev\Blog\Console\Command; use AlexPoletaev\Blog\Model\ResourceModel\Post as PostResource; use Magento\Framework\App\ResourceConnection; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class RemoveSampleDataCommand extends Command { private $resourceConnection; public function __construct( ResourceConnection $resourceConnection ) { parent::__construct(); $this->resourceConnection = $resourceConnection; } protected function configure() { $this->setName('alex_poletaev:blog:remove_sample_data') ->setDescription('Blog: remove sample data') ; parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output) { $connection = $this->resourceConnection->getConnection(); $connection->truncateTable($connection->getTableName(PostResource::TABLE_NAME)); if ($output->getVerbosity() > 1) { $output->writeln('<info>Sample data has been successfully removed.</info>'); } } }
Das Hauptmerkmal von Magento 2 ist die weit verbreitete Verwendung seiner eigenen Implementierung von
Dependency Injection . Damit Magenta weiß, welcher Schnittstelle die Implementierung entspricht, müssen diese Abhängigkeiten in der Datei di.xml angegeben werden. Gleichzeitig registrieren wir die neu erstellten Konsolenskripte in dieser Datei:
AlexPoletaev / Blog / etc / di.xml <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="AlexPoletaev\Blog\Api\Data\PostInterface" type="AlexPoletaev\Blog\Model\Post"/> <preference for="AlexPoletaev\Blog\Api\PostRepositoryInterface" type="AlexPoletaev\Blog\Model\PostRepository"/> <preference for="AlexPoletaev\Blog\Api\Data\PostSearchResultInterface" type="Magento\Framework\Api\SearchResults" /> <type name="Magento\Framework\Console\CommandList"> <arguments> <argument name="commands" xsi:type="array"> <item name="deploy_sample_data" xsi:type="object">AlexPoletaev\Blog\Console\Command\DeploySampleDataCommand</item> <item name="remove_sample_data" xsi:type="object">AlexPoletaev\Blog\Console\Command\RemoveSampleDataCommand</item> </argument> </arguments> </type> </config>
Registrieren Sie nun die Routen für die REST-API. Dies erfolgt in der Datei webapi.xml:
AlexPoletaev / Blog / etc / webapi.xml <?xml version="1.0"?> <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd"> <route url="/V1/blog/posts" method="POST"> <service class="AlexPoletaev\Blog\Api\PostRepositoryInterface" method="save"/> <resources> <resource ref="anonymous"/> </resources> </route> <route url="/V1/blog/posts/:id" method="DELETE"> <service class="AlexPoletaev\Blog\Api\PostRepositoryInterface" method="deleteById"/> <resources> <resource ref="anonymous"/> </resources> </route> <route url="/V1/blog/posts/:id" method="GET"> <service class="AlexPoletaev\Blog\Api\PostRepositoryInterface" method="get"/> <resources> <resource ref="anonymous"/> </resources> </route> <route url="/V1/blog/posts" method="GET"> <service class="AlexPoletaev\Blog\Api\PostRepositoryInterface" method="getList"/> <resources> <resource ref="anonymous"/> </resources> </route> </routes>
Hier teilen wir Magente mit, welche Schnittstelle und welche Methode von dieser Schnittstelle verwendet werden soll, wenn eine bestimmte URL und eine bestimmte http-Methode (POST, GET usw.) angefordert werden. Zur Vereinfachung wird auch eine
anonymous
Ressource verwendet, die es absolut jedem ermöglicht, an unsere API zu klopfen. Andernfalls müssen Sie Zugriffsrechte (ACLs) konfigurieren.
Höhepunkt
Bei allen weiteren Schritten wird davon ausgegangen, dass der Entwicklermodus aktiviert ist. Dies vermeidet unnötige Manipulationen durch die Bereitstellung von Inhaltsstatik und DI-Kompilierung.
Registrieren Sie unser neues Modul und führen Sie den folgenden Befehl aus:
php bin/magento setup:upgrade
.
Überprüfen Sie, ob eine neue Tabelle
alex_poletaev_blog_post erstellt wurde .
Laden Sie als Nächstes die Testdaten mit unserem benutzerdefinierten Skript:
php bin/magento -v alex_poletaev:blog:deploy_sample_data admin
Der
admin- Parameter in diesem Skript ist der
Benutzername aus der Tabelle
admin_user (er kann für Sie unterschiedlich sein), kurz
gesagt der Benutzer aus dem Admin-Bereich, der in die Spalte author_id geschrieben wird.
Jetzt können Sie mit dem Testen beginnen. Für Tests habe ich Magento 2.2.4, Domain
http://m224ce.local/
.
Eine Möglichkeit zum Testen der REST-API besteht darin,
http://m224ce.local/swagger
zu öffnen und die Swagger-Funktionalität zu verwenden.
getList
jedoch, dass die Methode
getList
dort nicht ordnungsgemäß funktioniert. Ich habe auch alle Methoden mit Curl getestet, Beispiele:
Holen Sie sich einen Artikel mit
id = 2 curl -X GET -H "Accept: application/json" "http://m224ce.local/rest/all/V1/blog/posts/2"
Die Antwort lautet:
{"id":2,"author_id":1,"title":"test title 2","content":"test content 2","created_at":"2018-06-06 21:35:54","updated_at":"2018-06-06 21:35:54"}
Holen Sie sich eine Liste der Artikel mit
author_id = 2 curl -g -X GET -H "Accept: application/json" "http://m224ce.local/rest/all/V1/blog/posts?searchCriteria[filterGroups][0][filters][0][field]=author_id&searchCriteria[filterGroups][0][filters][0][value]=1&searchCriteria[filterGroups][0][filters][0][conditionType]=eq"
Die Antwort lautet:
{"items":[{"id":1,"author_id":1,"title":"test title 1","content":"test content 1","created_at":"2018-06-06 21:35:54","updated_at":"2018-06-06 21:35:54"},{"id":2,"author_id":1,"title":"test title 2","content":"test content 2","created_at":"2018-06-06 21:35:54","updated_at":"2018-06-06 21:35:54"},{"id":3,"author_id":1,"title":"test title 3","content":"test content 3","created_at":"2018-06-06 21:35:54","updated_at":"2018-06-06 21:35:54"}],"search_criteria":{"filter_groups":[{"filters":[{"field":"author_id","value":"1","condition_type":"eq"}]}]},"total_count":3}
Artikel mit
id = 3 löschen curl -X DELETE -H "Accept: application/json" "http://m224ce.local/rest/all/V1/blog/posts/3"
Die Antwort lautet:
true
Speichern Sie den neuen Artikel
curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{"post": {"author_id": 1, "title": "test title 4", "content": "test content 4"}}' "http://m224ce.local/rest/all/V1/blog/posts"
Die Antwort lautet:
{"id":4,"author_id":1,"title":"test title 4","content":"test content 4","created_at":"2018-06-06 21:44:24","updated_at":"2018-06-06 21:44:24"}
Bitte beachten Sie, dass Sie für eine Anforderung mit der http POST-Methode den
Post- Schlüssel übergeben müssen, der tatsächlich dem Eingabeparameter ($ post) für die Methode entspricht
\AlexPoletaev\Blog\Api\PostRepositoryInterface::save()
Auflösung
Für diejenigen, die daran interessiert sind, was während der Anfrage passiert und wie Magenta sie verarbeitet, werde ich im Folgenden einige Links zu Methoden mit meinen Kommentaren geben. Wenn etwas nicht funktioniert, müssen diese Methoden zuerst belastet werden.
Der für die Bearbeitung der Anfrage verantwortliche Controller
\ Magento \ Webapi \ Controller \ Rest :: dispatch ()Als nächstes angerufen
\ Magento \ Webapi \ Controller \ Rest :: processApiRequest ()Viele andere Methoden werden in
processApiRequest
, aber die
processApiRequest
\ Magento \ Webapi \ Controller \ Rest \ InputParamsResolver :: resolve ()\ Magento \ Webapi \ Controller \ Rest \ Router :: match () - Eine bestimmte Route wird bestimmt (innerhalb der Methode
\Magento\Webapi\Model\Rest\Config::getRestRoutes()
werden alle geeigneten Routen aus der Anforderung aus der Anforderung
\Magento\Webapi\Model\Rest\Config::getRestRoutes()
). Das Routenobjekt enthält alle erforderlichen Daten zur Verarbeitung der Anforderung - Klasse, Methode, Zugriffsrechte usw.
\ Magento \ Framework \ Webapi \ ServiceInputProcessor :: process ()- verwendet
\Magento\Framework\Reflection\MethodsMap::getMethodParams()
, wobei Methodenparameter durch Reflektion gezogen werden
\ Magento \ Framework \ Webapi \ ServiceInputProcessor :: convertValue () - verschiedene Optionen zum Konvertieren eines Arrays in ein DataObject oder in ein Array aus einem DataObject
\ Magento \ Framework \ Webapi \ ServiceInputProcessor :: _ createFromArray () - direkte Konvertierung, bei der durch die Reflexion das Vorhandensein von Gettern und Setzern überprüft wird (denken Sie daran, ich habe oben gesagt, dass wir zu ihnen zurückkehren werden?) Und dass sie einen öffentlichen Bereich haben. Als nächstes wird das Objekt über die Setter mit Daten gefüllt.
Ganz am Ende in der Methode
\ Magento \ Webapi \ Controller \ Rest :: processApiRequest () , über das
call_user_func_array
Methode des Repository-Objekts aufgerufen.
Nachwort
Github-Modul-RepositoryEs gibt zwei Möglichkeiten zur Installation:
1) Über Komponisten. Fügen Sie dazu das folgende
repositories
Array in der Datei composer.json hinzu
{ "type": "git", "url": "https://github.com/alexpoletaev/magento2-blog-demo" }
Geben Sie dann den folgenden Befehl in das Terminal ein:
composer require alexpoletaev/magento2-blog-demo:dev-master
2) Laden Sie die Moduldateien herunter und kopieren Sie sie manuell in das Verzeichnis
app/code/AlexPoletaev/Blog
Unabhängig davon, für welche Methode Sie sich entscheiden, müssen Sie am Ende das Upgrade ausführen:
php bin/magento setup:upgrade
Ich hoffe, dieser Artikel ist für jemanden nützlich. Wenn Sie Kommentare, Vorschläge oder Fragen haben, können Sie diese gerne kommentieren. Vielen Dank für Ihre Aufmerksamkeit.