UNPKG

geography-apis-sdk

Version:

SDK for making requests to Geography APIs

170 lines (155 loc) 5.81 kB
/** * Represents an Rest client for making requests. */ class RestClient { /** * Creates an instance of the RestClient class. * @param {string} baseURL - The base URL of the API. * @param {string} apiKey - The API key for authentication. * @param {string} apiHost - The API host. */ constructor(baseURL, apiKey, apiHost) { /** * The base URL of the API. * @type {string} */ this.baseURL = baseURL; /** * The API key for authentication. * @type {string} */ this.apiKey = apiKey; /** * The API host. * @type {string} */ this.apiHost = apiHost; } /** * Makes a request to the API endpoint with the specified options. * @param {string} endpoint - The API endpoint to request. * @param {object} options - The options for the request (e.g., method, headers, body). * @returns {Promise<Object>} - A promise that resolves to the response body and headers. * @throws {Error} - If the request fails or returns an error response. */ async request(endpoint, options = {}) { try { const requestOptions = { method: options.method || 'GET', headers: { 'X-RapidAPI-Key': this.apiKey, 'X-RapidAPI-Host': this.apiHost, 'Access-Control-Allow-Headers': 'X-Requested-With', ...options.headers, // Merge the headers from options } }; delete requestOptions.method; // Remove 'method' from the options object const url = new URL(`${this.baseURL}${endpoint}`); if (options.params) { Object.entries(options.params).forEach(([key, value]) => { url.searchParams.append(key, value); }); } const response = await fetch(url.toString(), requestOptions); var body = [] const headers = response.headers; if (response.status === 204) { // No Content response return { body: [], headers }; } else if (response.ok || response.status === 206) { body = await response.json(); return { body, headers } } else { let errorData; try { errorData = await response.json(); } catch (error) { // Unable to parse error response as JSON throw new Error(`Request failed with status: ${response.status}`); } const errorMessage = errorData?.message || response.statusText; throw new Error(errorMessage); } } catch (error) { throw new Error(`Error making request: ${error.message}`); } } /** * Sends a GET request to the specified endpoint. * @param {string} endpoint - The endpoint to send the request to. * @param {object} params - The query parameters for the request. * @param {object} headers - The additional headers for the request. * @returns {Promise<Object>} - A promise that resolves to the response body and headers. * @throws {Error} - If an error occurs during the request or if the response is not successful. */ async get(endpoint, params = {}, headers = {}) { const url = new URL(`${this.baseURL}${endpoint}`); Object.entries(params).forEach(([key, value]) => { url.searchParams.append(key, value); }); try { const response = await fetch(url.toString(), { headers: { 'X-RapidAPI-Key': this.apiKey, 'X-RapidAPI-Host': this.apiHost, ...headers, // Merge additional headers with the default headers }, }); var body = [] const headers = response.headers; if (response.status === 204) { // No Content response return { body: [], headers }; } else if (response.ok || response.status === 206) { body = await response.json(); return { body, headers } } else { let errorData; try { errorData = await response.json(); } catch (error) { // Unable to parse error response as JSON throw new Error(`Request failed with status: ${response.status}`); } const errorMessage = errorData?.message || response.statusText; throw new Error(errorMessage); } } catch (error) { throw new Error(`Error making GET request: ${error.message}`); } } /** * Makes a call to the Geography API with the specified options. * @param {object} options - The options for the API call (e.g., headers, params). * @param {string} endpoint - The API endpoint to call. * @param {string} pathVariable - The path variable to append to the endpoint. * @param {class} type - The class to deserialize the API response into. * @returns {Promise<Object>} - A promise that resolves to the mapped response body and headers. * @throws {Error} - If an error occurs during the API call. */ async call(endpoint, pathVariable, options, type) { try { const requestOptions = { ...options, method: 'GET', }; const response = await this.request(`${endpoint}${pathVariable}`, requestOptions); const headers = response.headers; // Map API response to given Type @type if (Array.isArray(response.body)) { const body = response.body.map(data => { return new type(data); }); return { body, headers } } else if (typeof response === 'object' && response !== null) { const body = new type(response); return { body, headers } } else { throw new Error('No data found'); } } catch (error) { throw new Error(`Failed to call Geography API: ${error.message}`); } } } module.exports = RestClient;