geography-apis-sdk
Version:
SDK for making requests to Geography APIs
170 lines (155 loc) • 5.81 kB
JavaScript
/**
* 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;