Result based api call for ease of use .you can implements in any language
Last active
November 9, 2023 03:38
-
-
Save krabhi1/797074c46efa0a8616c424a1fc8a1d89 to your computer and use it in GitHub Desktop.
Result based api call for ease of use
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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