Question

I need to store my REST request within the file system - I have tried serializing the request object, but obviously the file size is quite a lot larger than the original.

I have run a test that allows me to store the payload as an object, then retrieve the data and un-serialize it. But as mentioned, not happy with the 10MB+ file size for a small payload of a few KB.

Is there any way I can get the original payload without extending the core? The only ways I can think to do it is either to BASE64 encode the original JSON data and pass it as a string - seems like a hack - perhaps enclose JSON in an XML field - but then it'd be an XML only REST method, which wouldn't be ideal.

Any ideas would be appreciated.

Était-ce utile?

La solution

Serializing the object will most likely serialize the entire PHP Object. That's the reason why you end up with a massive file. You only want to log the payload from that request.

I've wrote a module once that would log all API requests to the database for debugging purposes. The way I did it was with a plugin around the dispatch()-method of \Magento\Webapi\Controller\Rest. This is the code:

class Rest
{
    /**
     * @var Auto
     */
    protected $autoLogger;

    /**
     * @var ConfigHelper
     */
    protected $configHelper;

    /**
     * Rest constructor.
     * @param Auto $autoLogger
     */
    public function __construct(
        Auto $autoLogger,
        ConfigHelper $configHelper
    )
    {
        $this->autoLogger = $autoLogger;
        $this->configHelper = $configHelper;
    }

    /**
     * @param \Magento\Webapi\Controller\Rest $subject
     * @param callable $proceed
     * @param \Magento\Framework\App\RequestInterface|\Magento\Framework\Webapi\Rest\Request $request
     * @return mixed
     */
    public function aroundDispatch(
        \Magento\Webapi\Controller\Rest $subject,
        callable $proceed,
        \Magento\Framework\App\RequestInterface $request
    ) {
        if ($this->configHelper->isEnableApiDebugging()) {
            $this->autoLogger->setTitle('API: ' . $request->getPathInfo());
            $this->autoLogger->setType('API Debugger');
            try {
                $this->autoLogger->add('Request: ' . $request->getPathInfo());

                $params = [];
                foreach ($request->getParams() as $key => $value) {
                    $params[] = $key . ': ' . $value;
                }
                $this->autoLogger->add("Params:\n  " . implode("\n  ", $params));

                $headers = [];
                try {
                    foreach ($request->getHeaders() as $header) {
                        $headers[] = $header->toString();
                    }
                } catch (\Exception $exception) {
                    // Fail silently ...
                }

                $this->autoLogger->add("Headers:\n  " . implode("\n  ", $headers));
                if ($this->isAuthorizationRequest($request->getPathInfo())) {
                    $this->autoLogger
                        ->add("Body:\n  (Authorization request body is not logged because it contains the password)");
                } else {
                    $this->autoLogger->add('Body: ' . $request->getContent());
                }
            } catch (\Exception $exception) {
                $this->autoLogger->add(
                    'Exception before logging API request: ' . $exception->getMessage() . ' (' .
                        $exception->getFile() . '::' . $exception->getLine() . ')',
                    Log::LEVEL_ERROR
                );
            }
        }

        /** @var \Magento\Framework\Webapi\Rest\Response $returnValue */
        $returnValue = $proceed($request);

        if ($this->configHelper->isEnableApiDebugging()) {
            try {
                if ($this->isAuthorizationRequest($request->getPathInfo())) {
                    $this->autoLogger
                        ->add("Response:\n  (Response is not logged because it contains the authorization key)");
                } else {
                    $this->autoLogger->add('Response: ' . $returnValue->getBody());
                }
            } catch(\Exception $exception) {
                $this->autoLogger->add(
                    'Exception after logging API request: ' . $exception->getMessage(),
                    Log::LEVEL_ERROR
                );
            }
        }

        return $returnValue;
    }

    /**
     * @param string $pathInfo
     * @return bool
     */
    protected function isAuthorizationRequest(string $pathInfo) : bool
    {
        return preg_match('/integration\/(admin|customer)\/token/', $pathInfo) !== 0;
    }
}

The $autoLogger in this example is a class that would simply write data to the database. You could do something similar by writing it to a file or something.

Perhaps this can be of some help for you.

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top