Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 48b34cc

Browse files
authored
Merge pull request #2249 from magento-engcom/async-webapi-1
[Engcom] Add extension points to WebAPI to support different request processors
2 parents 449db18 + 2379fb3 commit 48b34cc

File tree

8 files changed

+488
-217
lines changed

8 files changed

+488
-217
lines changed

app/code/Magento/Webapi/Controller/Rest.php

Lines changed: 16 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@
1414
use Magento\Framework\Webapi\Request;
1515
use Magento\Framework\Webapi\Rest\Request as RestRequest;
1616
use Magento\Framework\Webapi\Rest\Response as RestResponse;
17-
use Magento\Framework\Webapi\Rest\Response\FieldsFilter;
1817
use Magento\Framework\Webapi\ServiceInputProcessor;
19-
use Magento\Framework\Webapi\ServiceOutputProcessor;
2018
use Magento\Store\Model\Store;
2119
use Magento\Store\Model\StoreManagerInterface;
2220
use Magento\Webapi\Controller\Rest\ParamsOverrider;
2321
use Magento\Webapi\Controller\Rest\Router;
2422
use Magento\Webapi\Controller\Rest\Router\Route;
25-
use Magento\Webapi\Model\Rest\Swagger\Generator;
23+
use Magento\Webapi\Controller\Rest\RequestProcessorPool;
2624

2725
/**
2826
* Front controller for WebAPI REST area.
@@ -32,7 +30,11 @@
3230
*/
3331
class Rest implements \Magento\Framework\App\FrontControllerInterface
3432
{
35-
/** Path for accessing REST API schema */
33+
/**
34+
* Path for accessing REST API schema
35+
*
36+
* @deprecated 100.3.0
37+
*/
3638
const SCHEMA_PATH = '/schema';
3739

3840
/**
@@ -94,11 +96,6 @@ class Rest implements \Magento\Framework\App\FrontControllerInterface
9496
*/
9597
protected $areaList;
9698

97-
/**
98-
* @var \Magento\Framework\Webapi\Rest\Response\FieldsFilter
99-
*/
100-
protected $fieldsFilter;
101-
10299
/**
103100
* @var \Magento\Framework\Session\Generic
104101
*/
@@ -111,31 +108,16 @@ class Rest implements \Magento\Framework\App\FrontControllerInterface
111108
protected $paramsOverrider;
112109

113110
/**
114-
* @var \Magento\Framework\Webapi\ServiceOutputProcessor
115-
*/
116-
protected $serviceOutputProcessor;
117-
118-
/**
119-
* @var \Magento\Webapi\Model\Rest\Swagger\Generator
111+
* @var RequestProcessorPool
120112
*/
121-
protected $swaggerGenerator;
113+
protected $requestProcessorPool;
122114

123115
/**
124116
* @var StoreManagerInterface
125117
* @deprecated 100.1.0
126118
*/
127119
private $storeManager;
128120

129-
/**
130-
* @var DeploymentConfig
131-
*/
132-
private $deploymentConfig;
133-
134-
/**
135-
* @var Rest\InputParamsResolver
136-
*/
137-
private $inputParamsResolver;
138-
139121
/**
140122
* Initialize dependencies
141123
*
@@ -149,11 +131,9 @@ class Rest implements \Magento\Framework\App\FrontControllerInterface
149131
* @param ErrorProcessor $errorProcessor
150132
* @param PathProcessor $pathProcessor
151133
* @param \Magento\Framework\App\AreaList $areaList
152-
* @param FieldsFilter $fieldsFilter
153134
* @param ParamsOverrider $paramsOverrider
154-
* @param ServiceOutputProcessor $serviceOutputProcessor
155-
* @param Generator $swaggerGenerator ,
156135
* @param StoreManagerInterface $storeManager
136+
* @param RequestProcessorPool $requestProcessorPool
157137
*
158138
* TODO: Consider removal of warning suppression
159139
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -169,11 +149,9 @@ public function __construct(
169149
ErrorProcessor $errorProcessor,
170150
PathProcessor $pathProcessor,
171151
\Magento\Framework\App\AreaList $areaList,
172-
FieldsFilter $fieldsFilter,
173152
ParamsOverrider $paramsOverrider,
174-
ServiceOutputProcessor $serviceOutputProcessor,
175-
Generator $swaggerGenerator,
176-
StoreManagerInterface $storeManager
153+
StoreManagerInterface $storeManager,
154+
RequestProcessorPool $requestProcessorPool
177155
) {
178156
$this->_router = $router;
179157
$this->_request = $request;
@@ -185,37 +163,9 @@ public function __construct(
185163
$this->_errorProcessor = $errorProcessor;
186164
$this->_pathProcessor = $pathProcessor;
187165
$this->areaList = $areaList;
188-
$this->fieldsFilter = $fieldsFilter;
189166
$this->paramsOverrider = $paramsOverrider;
190-
$this->serviceOutputProcessor = $serviceOutputProcessor;
191-
$this->swaggerGenerator = $swaggerGenerator;
192167
$this->storeManager = $storeManager;
193-
}
194-
195-
/**
196-
* Get deployment config
197-
*
198-
* @return DeploymentConfig
199-
*/
200-
private function getDeploymentConfig()
201-
{
202-
if (!$this->deploymentConfig instanceof \Magento\Framework\App\DeploymentConfig) {
203-
$this->deploymentConfig = \Magento\Framework\App\ObjectManager::getInstance()
204-
->get(\Magento\Framework\App\DeploymentConfig::class);
205-
}
206-
return $this->deploymentConfig;
207-
}
208-
209-
/**
210-
* Set deployment config
211-
*
212-
* @param \Magento\Framework\App\DeploymentConfig $deploymentConfig
213-
* @return void
214-
* @deprecated 100.1.0
215-
*/
216-
public function setDeploymentConfig(\Magento\Framework\App\DeploymentConfig $deploymentConfig)
217-
{
218-
$this->deploymentConfig = $deploymentConfig;
168+
$this->requestProcessorPool = $requestProcessorPool;
219169
}
220170

221171
/**
@@ -234,15 +184,13 @@ public function dispatch(\Magento\Framework\App\RequestInterface $request)
234184
$this->areaList->getArea($this->_appState->getAreaCode())
235185
->load(\Magento\Framework\App\Area::PART_TRANSLATE);
236186
try {
237-
if ($this->isSchemaRequest()) {
238-
$this->processSchemaRequest();
239-
} else {
240-
$this->processApiRequest();
241-
}
187+
$processor = $this->requestProcessorPool->getProcessor($this->_request);
188+
$processor->process($this->_request);
242189
} catch (\Exception $e) {
243190
$maskedException = $this->_errorProcessor->maskException($e);
244191
$this->_response->setException($maskedException);
245192
}
193+
246194
return $this->_response;
247195
}
248196

@@ -268,6 +216,7 @@ protected function getCurrentRoute()
268216
if (!$this->_route) {
269217
$this->_route = $this->_router->match($this->_request);
270218
}
219+
271220
return $this->_route;
272221
}
273222

@@ -290,60 +239,6 @@ protected function checkPermissions()
290239
}
291240
}
292241

293-
/**
294-
* Execute schema request
295-
*
296-
* @return void
297-
*/
298-
protected function processSchemaRequest()
299-
{
300-
$requestedServices = $this->_request->getRequestedServices('all');
301-
$requestedServices = $requestedServices == Request::ALL_SERVICES
302-
? $this->swaggerGenerator->getListOfServices()
303-
: $requestedServices;
304-
$responseBody = $this->swaggerGenerator->generate(
305-
$requestedServices,
306-
$this->_request->getScheme(),
307-
$this->_request->getHttpHost(false),
308-
$this->_request->getRequestUri()
309-
);
310-
$this->_response->setBody($responseBody)->setHeader('Content-Type', 'application/json');
311-
}
312-
313-
/**
314-
* Execute API request
315-
*
316-
* @return void
317-
* @throws AuthorizationException
318-
* @throws \Magento\Framework\Exception\InputException
319-
* @throws \Magento\Framework\Webapi\Exception
320-
*/
321-
protected function processApiRequest()
322-
{
323-
$inputParams = $this->getInputParamsResolver()->resolve();
324-
325-
$route = $this->getInputParamsResolver()->getRoute();
326-
$serviceMethodName = $route->getServiceMethod();
327-
$serviceClassName = $route->getServiceClass();
328-
329-
$service = $this->_objectManager->get($serviceClassName);
330-
/** @var \Magento\Framework\Api\AbstractExtensibleObject $outputData */
331-
$outputData = call_user_func_array([$service, $serviceMethodName], $inputParams);
332-
$outputData = $this->serviceOutputProcessor->process(
333-
$outputData,
334-
$serviceClassName,
335-
$serviceMethodName
336-
);
337-
if ($this->_request->getParam(FieldsFilter::FILTER_PARAMETER) && is_array($outputData)) {
338-
$outputData = $this->fieldsFilter->filter($outputData);
339-
}
340-
$header = $this->getDeploymentConfig()->get(ConfigOptionsListConstants::CONFIG_PATH_X_FRAME_OPT);
341-
if ($header) {
342-
$this->_response->setHeader('X-Frame-Options', $header);
343-
}
344-
$this->_response->prepareResponse($outputData);
345-
}
346-
347242
/**
348243
* Validate request
349244
*
@@ -365,20 +260,4 @@ protected function validateRequest()
365260
throw new \Magento\Framework\Webapi\Exception(__('Cannot perform GET operation with store code \'all\''));
366261
}
367262
}
368-
369-
/**
370-
* The getter function to get InputParamsResolver object
371-
*
372-
* @return \Magento\Webapi\Controller\Rest\InputParamsResolver
373-
*
374-
* @deprecated 100.1.0
375-
*/
376-
private function getInputParamsResolver()
377-
{
378-
if ($this->inputParamsResolver === null) {
379-
$this->inputParamsResolver = \Magento\Framework\App\ObjectManager::getInstance()
380-
->get(\Magento\Webapi\Controller\Rest\InputParamsResolver::class);
381-
}
382-
return $this->inputParamsResolver;
383-
}
384263
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Webapi\Controller\Rest;
8+
9+
/**
10+
* Request processor interface
11+
*/
12+
interface RequestProcessorInterface
13+
{
14+
/**
15+
* Executes the logic to process the request
16+
*
17+
* @param \Magento\Framework\Webapi\Rest\Request $request
18+
* @return void
19+
* @throws \Magento\Framework\Exception\AuthorizationException
20+
* @throws \Magento\Framework\Exception\InputException
21+
* @throws \Magento\Framework\Webapi\Exception
22+
*/
23+
public function process(\Magento\Framework\Webapi\Rest\Request $request);
24+
25+
/**
26+
* Method should return true for all the request current processor can process.
27+
*
28+
* Invoked in the loop for all registered request processors. The first one wins.
29+
*
30+
* @param \Magento\Framework\Webapi\Rest\Request $request
31+
* @return bool
32+
*/
33+
public function canProcess(\Magento\Framework\Webapi\Rest\Request $request);
34+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Webapi\Controller\Rest;
8+
9+
/**
10+
* Request Processor Pool
11+
*/
12+
class RequestProcessorPool
13+
{
14+
15+
/**
16+
* @var array
17+
*/
18+
private $requestProcessors;
19+
20+
/**
21+
* Initial dependencies
22+
*
23+
* @param RequestProcessorInterface[] $requestProcessors
24+
*/
25+
public function __construct($requestProcessors = [])
26+
{
27+
$this->requestProcessors = $requestProcessors;
28+
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*
33+
* @throws \Magento\Framework\Webapi\Exception
34+
* return RequestProcessorInterface
35+
*/
36+
public function getProcessor(\Magento\Framework\Webapi\Rest\Request $request)
37+
{
38+
foreach ($this->requestProcessors as $processor) {
39+
if ($processor->canProcess($request)) {
40+
return $processor;
41+
}
42+
}
43+
44+
throw new \Magento\Framework\Webapi\Exception(
45+
__('Specified request cannot be processed.'),
46+
0,
47+
\Magento\Framework\Webapi\Exception::HTTP_BAD_REQUEST
48+
);
49+
}
50+
}

app/code/Magento/Webapi/Controller/Rest/Router/Route.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,14 @@ public function getParameters()
241241
{
242242
return $this->parameters;
243243
}
244+
245+
/**
246+
* Get route path.
247+
*
248+
* @return string
249+
*/
250+
public function getRoutePath()
251+
{
252+
return $this->route;
253+
}
244254
}

0 commit comments

Comments
 (0)