public function handleJsonRequest($jsonRequest)
    {
        // Batch requests
        if (\is_array($jsonRequest)) {
            $jsonResponse = [];
            foreach ($jsonRequest as $request) {
                $jsonResponse[] = $this->handleJsonRequest($request);
            }

            return $jsonResponse;
        }

        if ($this->stopwatch) {
            $this->stopwatch->start('rpc.execute');
        }

        try {
            $this->dispatch(Event\JsonRequestEvent::EVENT, new Event\JsonRequestEvent($jsonRequest));

            $metadata = $this->getMethod($jsonRequest);
            $isCache = $this->isCacheSupport($jsonRequest);
            $cacheId = $jsonRequest->getHash();

            $jsonResponse = new JsonResponse($jsonRequest);
            // Cache
            if (true === $isCache && true === $this->getCache()->contains($cacheId)) {
                $jsonResponse->setResult($this->getCache()->fetch($cacheId));
                $isCache = false; // we don't want warm check without left ttl
            }

            $result = $jsonResponse->getResult();
            if (null === $result) { // if not cache
                $result = $this->executeJsonRequest($metadata, $jsonRequest);
            }

            if ($result instanceof JsonResponse) {
                $jsonResponse = $result;
                $jsonResponse->setRequest($jsonRequest);
            } else {
                $jsonResponse->setResult($this->serialize($result));
            }

            // Save cache
            $isCache && $this->cache->save($cacheId, $jsonResponse->getResult(), $metadata->getCache());

            $this->dispatch(Event\JsonResponseEvent::EVENT, new Event\JsonResponseEvent($jsonResponse));
        } catch (\Exception $exception) {
            $jsonResponse = $this->createJsonResponseFromException($exception, $jsonRequest);
        }

        if ($this->stopwatch) {
            $this->stopwatch->stop('rpc.execute');
        }

        return $jsonResponse;
    }