def test_rest_api_url(self):
        url = utils.rest_api_url(None)
        self.assertEqual(CONSTANTS.REST_URLS.get("ndax_main"), url)

        url = utils.rest_api_url("ndax_main")
        self.assertEqual(CONSTANTS.REST_URLS.get("ndax_main"), url)

        url = utils.rest_api_url("ndax_testnet")
        self.assertEqual(CONSTANTS.REST_URLS.get("ndax_testnet"), url)
    async def _api_request(self,
                           method: str,
                           path_url: str,
                           params: Optional[Dict[str, Any]] = None,
                           data: Optional[Dict[str, Any]] = None,
                           is_auth_required: bool = False,
                           limit_id: Optional[str] = None) -> Union[Dict[str, Any], List[Any]]:
        """
        Sends an aiohttp request and waits for a response.
        :param method: The HTTP method, e.g. get or post
        :param path_url: The path url or the API end point
        :param params: The query parameters of the API request
        :param params: The body parameters of the API request
        :param is_auth_required: Whether an authentication is required, when True the function will add encrypted
        signature to the request.
        :param limit_id: The id used for the API throttler. If not supplied, the `path_url` is used instead.
        :returns A response in json format.
        """
        url = ndax_utils.rest_api_url(self._domain) + path_url
        client = await self._http_client()

        try:
            if is_auth_required:
                headers = self._auth.get_auth_headers()
            else:
                headers = self._auth.get_headers()

            limit_id = limit_id or path_url
            if method == "GET":
                async with self._throttler.execute_task(limit_id):
                    response = await client.get(url, headers=headers, params=params)
            elif method == "POST":
                async with self._throttler.execute_task(limit_id):
                    response = await client.post(url, headers=headers, data=ujson.dumps(data))
            else:
                raise NotImplementedError(f"{method} HTTP Method not implemented. ")

            data = await response.text()
            if data == CONSTANTS.API_LIMIT_REACHED_ERROR_MESSAGE:
                raise Exception(f"The exchange API request limit has been reached (original error '{data}')")

            parsed_response = await response.json()

        except ValueError as e:
            self.logger().error(f"{str(e)}")
            raise ValueError(f"Error authenticating request {method} {url}. Error: {str(e)}")
        except Exception as e:
            raise IOError(f"Error parsing data from {url}. Error: {str(e)}")
        if response.status != 200 or (isinstance(parsed_response, dict) and not parsed_response.get("result", True)):
            self.logger().error(f"Error fetching data from {url}. HTTP status is {response.status}. "
                                f"Message: {parsed_response} "
                                f"Params: {params} "
                                f"Data: {data}")
            raise Exception(f"Error fetching data from {url}. HTTP status is {response.status}. "
                            f"Message: {parsed_response} "
                            f"Params: {params} "
                            f"Data: {data}")

        return parsed_response