Skip to content

Instantly share code, notes, and snippets.

@krabhi1
Last active November 9, 2023 03:38
Show Gist options
  • Save krabhi1/797074c46efa0a8616c424a1fc8a1d89 to your computer and use it in GitHub Desktop.
Save krabhi1/797074c46efa0a8616c424a1fc8a1d89 to your computer and use it in GitHub Desktop.
Result based api call for ease of use

api-call

Result based api call for ease of use .you can implements in any language

export interface Result<T = any> {
result?: T
errorMessage: string
error?: any
statusCode: number
}
export interface RequestQuery {
path?: string;
method?: "GET" | "POST" | "DELETE" | "PATCH";
headers?: Record<string, string>;
query?: Record<string, any>;
body?: any;
authToken?: string
onSuccess?: (res: Response, result: Result) => Promise<Result>
onFail?: (res: Response, result: Result) => Promise<Result>
}
const server_url = import.meta.env.VITE_SERVER_URL
function objectToQueryString(obj: { [key: string]: any }): string {
const parts: string[] = [];
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
parts.push(`${key}=${value}`);
}
}
return parts.join('&');
}
export async function apiCall<T>(query: RequestQuery) {
try {
const { path, method = "GET", headers = {}, query: params = {}, body, authToken } = query;
// Construct the URL with query parameters
let url = path || "";
url += "?" + objectToQueryString(params)
console.log(url)
if (authToken) {
headers['Authorization'] = `Bearer ${authToken}`;
}
const requestOptions: RequestInit = {
method,
headers: {
...headers,
},
redirect: 'follow'
};
if (body) {
requestOptions.body = typeof body == 'object' ? JSON.stringify(body) : body
}
const response = await fetch(url, requestOptions);
let result: Result<T> = {
errorMessage: "",
statusCode: response.status,
};
if (response.ok) {
if (query.onSuccess) {
result = await query.onSuccess(response, result)
}
else {
result.result = await response.json()
}
} else {
if (query.onFail) {
result = await query.onFail(response, result)
}
else {
result = await response.json()
}
console.log(result)
}
return result;
} catch (error: any) {
return {
result: undefined,
errorMessage: error.message,
error,
statusCode: 500,
};
}
}
export async function serverApiCall<T>(query: RequestQuery) {
query.path = server_url + query.path
return apiCall<T>({
async onSuccess(res, result) {
return await res.json()
},
async onFail(res, result) {
return await res.json()
},
...query
})
}
export async function authSafeServerApiCall<T>(query: RequestQuery) {
query.path = server_url + query.path
query.authToken = getAccessTokenCookies()!
return authSafeApiCall<T>(query)
}
export async function googleApiCall<T>(query: RequestQuery) {
query.path = "https://www.googleapis.com" + query.path
query.authToken = getAccessTokenCookies()!
return authSafeApiCall<T>({
async onSuccess(res, result) {
result.result = await res.json()
return result
},
async onFail(res, result) {
result.error = await res.json()
return result
},
...query
})
}
export async function authSafeApiCall<T>(query: RequestQuery) {
const result = await apiCall<T>(query)
if (result.statusCode == 401) {
//token is expires need one
const tokenResult = await refreshAccessToken();
if (!tokenResult) {
//redirect to login route
window.location.href = '/login';
}
query.authToken = getAccessTokenCookies()!
return apiCall<T>(query)
}
return result
}
export async function getAccessToken(code: string) {
const result = await serverApiCall<{
google_access_token: string;
token: string;
}>({
path: "/tokens",
query: {
code
},
method: 'GET'
})
return result
}
export async function refreshAccessToken() {
const result = await serverApiCall<{ google_access_token: string }>({
path: "/google/refresh/access_token",
authToken: getTokenCookies()!,
method: 'GET'
})
if (result.result) {
setAccessTokenCookies(result.result.google_access_token)
}
return result.result ? true : false
}
async someFunction(){
const accessCode = await getAccessToken(code);
if (accessCode.result) {
//do with result
} else {
//do with error
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment