Skip to content
This repository has been archived by the owner on May 20, 2019. It is now read-only.

Change Webapi extension to use Inject Pool logic #1

Merged
merged 19 commits into from
Mar 21, 2018

Conversation

nuzil
Copy link

@nuzil nuzil commented Jan 18, 2018

Description

We extended Magento/Webapi extension. This allowed us to use Request Processors Pool and avoid of using if/else statements in \Magento\Webapi\Controller\Rest.php

So now any new processor can be easily added via webapi_rest/di.xml file in any extension.

This modification will add much more flexibility in Magento customisations.

Manual testing scenarios

Here is no new feature developed, so Manual test will be in testing default Magento API calls

…stead of if/else statements in Rest.php

This will add a possibility to add new Processors to handle API requests
@@ -0,0 +1,28 @@
<?php
/**
* Created by PhpStorm.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use same header as elsewhere in Magento. Just configured Travis for the project, so your next commit should trigger static tests.

return $requestProcessor;
}
}
throw new \Magento\Framework\Exception\NotFoundException(__('Specified request does not match any route.'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception text should indicate that the request cannot be processed, does not match any route is too coupled with REST

@@ -172,7 +179,8 @@ public function __construct(
ParamsOverrider $paramsOverrider,
ServiceOutputProcessor $serviceOutputProcessor,
Generator $swaggerGenerator,
StoreManagerInterface $storeManager
StoreManagerInterface $storeManager,
RequestProcessorPool $requestProcessorPool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to follow Backward Compatibility
ObjectManager::getInstance()->create(...::class)

@@ -172,7 +179,8 @@ public function __construct(
ParamsOverrider $paramsOverrider,
ServiceOutputProcessor $serviceOutputProcessor,
Generator $swaggerGenerator,
StoreManagerInterface $storeManager
StoreManagerInterface $storeManager,
RequestProcessorPool $requestProcessorPool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to operate with RequestProcessorInterface
Pool it will be one of implementation of RequestProcessorInterface

Underhood of RequestProcessorInterface we can resolve proper processor by request and call process method

* @param \Magento\Framework\Webapi\Rest\Request $request
* @return bool
*/
public function canProcess(\Magento\Framework\Webapi\Rest\Request $request);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to remove this method from interface
This is part of internal implementation but not part of API

/**
* @var \Magento\Webapi\Model\Rest\Swagger\Generator
*/
protected $swaggerGenerator;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls use in all places private access for properties and methods
It should not be part of class contract

} else {
$this->processApiRequest();
}
$requestProcessor = $this->requestProcessorPool->getRequestProcessor($this->_request);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, it will be

$this->requestProcessor->process($request); // $this->requestProcessor is RequestProcessorInterface

*/
public function getRequestProcessor(\Magento\Framework\Webapi\Rest\Request $request)
{
foreach ($this->requestProcessors as $requestProcessor) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method process could return same state, and pool processor will decide next iteration based on this return status
Statuses can be constants in this RequestProcessorInterface

foreach ($this->requestProcessors as $requestProcessor) {
            if (self::PROCESS_STATUS_SUCCESSFUL === $requestProcessor->process($request)) {
                return;
            }
        }

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or more applicable way

if (!isset($this->processors[$request->getPathInfo()])) {
    throw new \Magento\Framework\Exception\NotFoundException(__('Specified request does not match any route.'));
}
$processor = $this->objectmanager->get($this->processors[$request->getPathInfo()]);
$processor->process();

di.xml

// use string but not object for loading of processors by request
<item key="scheme" type="string">SchemeProcessor
<item key="V1" type="string">SyncProcessor
<item key="async" type="string">AsyncProcessor

And my vote is second way

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In second case we can avoid sorting

namespace Magento\Webapi\Controller\Rest;


class RequestProcessorPool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also implement RequestProcessorInterface
It is only one private case of implementation

*/
public function getRequestProcessor(\Magento\Framework\Webapi\Rest\Request $request)
{
foreach ($this->requestProcessors as $requestProcessor) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or more applicable way

if (!isset($this->processors[$request->getPathInfo()])) {
    throw new \Magento\Framework\Exception\NotFoundException(__('Specified request does not match any route.'));
}
$processor = $this->objectmanager->get($this->processors[$request->getPathInfo()]);
$processor->process();

di.xml

// use string but not object for loading of processors by request
<item key="scheme" type="string">SchemeProcessor
<item key="V1" type="string">SyncProcessor
<item key="async" type="string">AsyncProcessor

And my vote is second way

*/
public function getRequestProcessor(\Magento\Framework\Webapi\Rest\Request $request)
{
foreach ($this->requestProcessors as $requestProcessor) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In second case we can avoid sorting

class SchemaRequestProcessor implements RequestProcessorInterface
{
/** Path for accessing REST API schema */
const SCHEMA_PATH = '/schema';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to di


class SynchronousRequestProcessor implements RequestProcessorInterface
{
const SYNC_PATH = "/V1/";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to di

* @param array $requestProcessors
* @return array
*/
protected function _getSortedRequestProcessors($requestProcessors) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove sorting if we will have mapping between pathInfo and processor class

Pavel added 2 commits January 24, 2018 11:31
 - added magento annotations to new created files in module;
 - modified rest controller - removed unnecessary depenancy and methods, modified dispatch method;
 - modified \Magento\Webapi\Controller\Rest\RequestProcessorInterface interface and classes that implement it - removed "canProcess" method;
 - modified \Magento\Webapi\Controller\Rest\RequestProcessorPool - now it implements RequestProcessorInterface, removed methods "_getSortedRequestProcessors" and "getRequestProcessor",
added "process" mathods which match rest request processor and call it "process" method;
 - modified webapi_rest/di.xml
<arguments>
<argument name="requestProcessors" xsi:type="array">
<item name="schema" xsi:type="string">Magento\Webapi\Controller\Rest\SchemaRequestProcessor</item>
<item name="V1" xsi:type="string">Magento\Webapi\Controller\Rest\SynchronousRequestProcessor</item>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be called V1SynchronousRequestProcessor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we hide "V1" from the configuration file and have just "sync"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question about your second comment:
with current implementation we are detecting parts of URL and routing requests automatically.
If we have to add "sync" part here, then we again have to add constants to the Controller to have correct mapping between V1 and Sync processor.

Copy link

@paliarush paliarush Feb 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current implementation is confusing, because it is not obvious that the processor name will be used as a pattern to match request URLs.

Better to implement canProcess()/match() method on the RequestProcessor interface and in the pool have implementation like:

        foreach ($this->requestProcessors as $requestProcessor) {
            if ($requestProcessor->canProcess($request)) {
                $requestProcessor->process($request);
            }
        }

Then we can use meaningful names for the request processors in di.xml, like schemaRequestProcessor and synchronousRequestProcessor

I know that @naydav requested current implementation. So feel free to keep it as is.

Vasiliev.A added 3 commits February 1, 2018 16:21
… class and method in topic config when request/schema attribute is wrapper class of real topic service class
Copy link

@paliarush paliarush left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good progress overall, thank you for working on this feature.

use Magento\Framework\View\Element\Template;

/**
* Class Index

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add meaningful descriptions to all new classes and methods in the CR.

/**
* Path for accessing REST API schema
*
* @todo need to change logic in \Magento\Webapi\Model\Rest\Swagger\Generator::generateSchema()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There must be no @todo merged to the mainline. Please create a ticket instead.

$this->_objectManager = $objectManager;
$this->_appState = $appState;
$this->authorization = $authorization;
$this->_router = $router;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such padding is valid for annotations, however we should not use it for the code. The reason is when you add new field, which is longer than all existing ones, padding for all other fields will have to be adjusted. I would recommend not using it for annotations as well, for the same reason.

Please adjust all similar occurrences in the PR.

@@ -260,13 +210,14 @@ protected function isSchemaRequest()
*
* @return Route
* @deprecated 100.1.0
* @see \Magento\Webapi\Controller\Rest\InputParamsResolver::getRoute
* @see \Magento\Webapi\Controller\Rest\InputParamsResolver::getRoute

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid padding, please adjust across current PR.

@@ -0,0 +1,47 @@
<?php
/***

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra asterisk should be removed.

@@ -38,6 +38,7 @@
</xs:choice>
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="schemaType" name="schema" use="optional"/>
<xs:attribute type="schemaType" name="serviceSchema" use="optional"/>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please explain the purpose of this change.

@@ -172,6 +173,7 @@ protected function setUp()

public function testDispatchSchemaRequest()
{
$this->markTestSkipped("testDispatchAllSchemaRequest temporary skipped");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot merge any temporary test skips.

@@ -154,7 +154,8 @@ protected function setUp()
]
);

$this->_restController->setDeploymentConfig($this->deploymentConfigMock);
/** @TODO Commented method "setDeploymentConfig" because method removed from class, will remove in future */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot merge any TODOs, please create ticket instead.

/**
* @var RestResponse
*/
protected $_response;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make all these properties private and remove underscore from the names.

use Magento\Framework\Config\ConfigOptionsListConstants;

/**
* REST request processor for general synchronous requests

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider removing general.

@nuzil
Copy link
Author

nuzil commented Feb 13, 2018

Just a small comment to last PR update: we remover Swagger part from it, cause its not ready and needed additional implementation, we will integrate it in another PR

@@ -38,6 +38,7 @@
</xs:choice>
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="schemaType" name="schema" use="optional"/>
<xs:attribute type="schemaType" name="service_schema" use="optional"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed in the EE pull request, let's avoid making changed to communication.xsd. Instead we can get rid of the OperationInterface wrapper from the \Magento\WebapiAsync\Model\AsyncBulkPublisher::scheduleAsyncBulk and publish messages with the schema which corresponds to the topic configuration.

vrann added a commit that referenced this pull request Mar 19, 2018
magento-engcom-team pushed a commit that referenced this pull request Jun 25, 2018
[Forwardport] Fixed typo mistake in function comment
magento-engcom-team pushed a commit that referenced this pull request Jul 2, 2018
[Forwardport] When searching for the title if search for all the segments that has …
magento-engcom-team pushed a commit that referenced this pull request Jul 27, 2018
Fixed a grammatical error on the vault tooltip
magento-engcom-team pushed a commit that referenced this pull request Sep 22, 2018
[Backport] Use route ID when creating secret keys in backend menus instead of route name
magento-engcom-team pushed a commit that referenced this pull request Oct 11, 2018
magento-engcom-team pushed a commit that referenced this pull request Oct 25, 2018
magento-engcom-team pushed a commit that referenced this pull request Oct 25, 2018
Fixed issues-18534: 2 wysiwyg on catalog category edit page
magento-engcom-team pushed a commit that referenced this pull request Oct 27, 2018
magento-engcom-team pushed a commit that referenced this pull request Oct 30, 2018
magento-engcom-team pushed a commit that referenced this pull request Oct 31, 2018
magento-engcom-team pushed a commit that referenced this pull request Nov 5, 2018
Remove unnecesary "header" block redeclaration
magento-engcom-team pushed a commit that referenced this pull request Nov 6, 2018
magento-engcom-team pushed a commit that referenced this pull request Nov 22, 2018
magento-engcom-team pushed a commit that referenced this pull request Nov 22, 2018
magento-engcom-team pushed a commit that referenced this pull request Nov 30, 2018
magento-engcom-team pushed a commit that referenced this pull request Dec 6, 2018
magento-engcom-team pushed a commit that referenced this pull request Dec 6, 2018
magento-engcom-team pushed a commit that referenced this pull request Dec 9, 2018
magento-engcom-team pushed a commit that referenced this pull request Dec 21, 2018
magento-engcom-team pushed a commit that referenced this pull request Dec 21, 2018
Missing setTotalCount on $searchResults object in getList method
magento-engcom-team pushed a commit that referenced this pull request Jan 23, 2019
removes extra dot on "How to run Magento" in phpserve/README.md
magento-engcom-team pushed a commit that referenced this pull request Feb 13, 2019
Add Brazilian Credit Cards Support #1
magento-engcom-team pushed a commit that referenced this pull request Feb 13, 2019
magento-engcom-team pushed a commit that referenced this pull request Feb 25, 2019
[Forwardport] 'Fixes-for-customer-login-page-input-field' :: On customer login page…
magento-engcom-team pushed a commit that referenced this pull request Mar 11, 2019
magento-engcom-team pushed a commit that referenced this pull request Apr 5, 2019
merge from magento/magento2
magento-engcom-team pushed a commit that referenced this pull request Apr 5, 2019
Removed two times zlib.output_compression on
magento-engcom-team pushed a commit that referenced this pull request Apr 23, 2019
magento-engcom-team pushed a commit that referenced this pull request May 6, 2019
magento-engcom-team pushed a commit that referenced this pull request May 10, 2019
…sh-1

Changed canonical_url to relative_url
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants