- Method: method
        - URL: url.format(**url_params)
        - Parameter: query_params & apiKey=api_key
        - Request Body(data): request_params

def do(self, method, url, url_params={}, query_params={}, request_params={}):
        """
        - Method: method
        - URL: url.format(**url_params)
        - Parameter: query_params & apiKey=api_key
        - Request Body(data): request_params
        """
        _url = url.format(**url_params).lstrip("/")
        _endpoint = self.endpoint.format(path=_url)
        _headers = {"Content-Type": "application/x-www-form-urlencoded"}

        request_params = BacklogClient.remove_mb4(request_params)

        resp = None

        method = method.lower().strip()
        query_params.update({"apiKey": self.api_key})
        if method == "get":
            resp = requests.get(_endpoint, params=query_params)
        elif method == "patch":
            resp = requests.patch(
                _endpoint, params=query_params, data=request_params, headers=_headers)
        elif method == "post":
            resp = requests.post(
                _endpoint, params=query_params, data=request_params, headers=_headers)
        elif method == "delete":
            resp = requests.delete(
                _endpoint, params=query_params, data=request_params, headers=_headers)
        else:
            raise Exception("Unsupported Method")

        if resp.status_code >= 400:
            raise Exception(resp, resp.text)

        if resp.status_code == 204:
            # 204 NO_CONTENT is blank response
            # used in star
            return None

        return resp.json()