Skip to content

Commit

Permalink
use fetch api instead of axios
Browse files Browse the repository at this point in the history
  • Loading branch information
alan2207 committed Sep 1, 2024
1 parent 1a00c38 commit 740e00f
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 54 deletions.
1 change: 0 additions & 1 deletion apps/nextjs-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"@radix-ui/react-switch": "^1.0.3",
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-query-devtools": "^5.32.0",
"axios": "^1.6.8",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.11",
Expand Down
4 changes: 2 additions & 2 deletions apps/nextjs-app/src/features/comments/api/get-comments.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/react-query';

import { api, attachCookie } from '@/lib/api-client';
import { api } from '@/lib/api-client';
import { QueryConfig } from '@/lib/react-query';
import { Comment, Meta } from '@/types/api';

Expand All @@ -18,7 +18,7 @@ export const getComments = ({
discussionId,
page,
},
headers: attachCookie(cookie).headers,
cookie,
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useQuery, queryOptions } from '@tanstack/react-query';

import { api, attachCookie } from '@/lib/api-client';
import { api } from '@/lib/api-client';
import { QueryConfig } from '@/lib/react-query';
import { Discussion } from '@/types/api';

Expand All @@ -12,7 +12,7 @@ export const getDiscussion = ({
cookie?: string;
}): Promise<{ data: Discussion }> => {
return api.get(`/discussions/${discussionId}`, {
headers: attachCookie(cookie).headers,
cookie,
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { queryOptions, useQuery } from '@tanstack/react-query';

import { api, attachCookie } from '@/lib/api-client';
import { api } from '@/lib/api-client';
import { QueryConfig } from '@/lib/react-query';
import { Discussion, Meta } from '@/types/api';

Expand All @@ -14,7 +14,7 @@ export const getDiscussions = (
params: {
page,
},
headers: attachCookie(cookie).headers,
cookie,
});
};

Expand Down
115 changes: 79 additions & 36 deletions apps/nextjs-app/src/lib/api-client.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,91 @@
import Axios, { InternalAxiosRequestConfig } from 'axios';

import { useNotifications } from '@/components/ui/notifications';
import { env } from '@/config/env';

function authRequestInterceptor(config: InternalAxiosRequestConfig) {
if (config.headers) {
config.headers.Accept = 'application/json';
}
type RequestOptions = {
method?: string;
headers?: Record<string, string>;
body?: any;
cookie?: string;
params?: Record<string, string | number | boolean | undefined | null>;
cache?: RequestCache;
next?: NextFetchRequestConfig;
};

config.withCredentials = true;
return config;
function buildUrlWithParams(
url: string,
params?: RequestOptions['params'],
): string {
if (!params) return url;
const filteredParams = Object.fromEntries(
Object.entries(params).filter(
([, value]) => value !== undefined && value !== null,
),
);
if (Object.keys(filteredParams).length === 0) return url;
const queryString = new URLSearchParams(
filteredParams as Record<string, string>,
).toString();
return `${url}?${queryString}`;
}

export const api = Axios.create({
baseURL: env.API_URL,
});

api.interceptors.request.use(authRequestInterceptor);
api.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
const message = error.response?.data?.message || error.message;
useNotifications.getState().addNotification({
type: 'error',
title: 'Error',
message,
});
async function fetchApi<T>(
url: string,
options: RequestOptions = {},
): Promise<T> {
const {
method = 'GET',
headers = {},
body,
cookie,
params,
cache = 'no-store',
next,
} = options;
const fullUrl = buildUrlWithParams(`${env.API_URL}${url}`, params);

return Promise.reject(error);
},
);

// if the endpoint requires the visiting user to be authenticated,
// attaching cookies is required for requests made on the server side
export const attachCookie = (
cookie?: string,
headers?: Record<string, string>,
) => {
return {
const response = await fetch(fullUrl, {
method,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...headers,
...(cookie ? { Cookie: cookie } : {}),
},
};
body: body ? JSON.stringify(body) : undefined,
credentials: 'include',
cache,
next,
});

if (!response.ok) {
const message = (await response.json()).message || response.statusText;
if (typeof window !== 'undefined') {
useNotifications.getState().addNotification({
type: 'error',
title: 'Error',
message,
});
}
throw new Error(message);
}

return response.json();
}

export const api = {
get<T>(url: string, options?: RequestOptions): Promise<T> {
return fetchApi<T>(url, { ...options, method: 'GET' });
},
post<T>(url: string, body?: any, options?: RequestOptions): Promise<T> {
return fetchApi<T>(url, { ...options, method: 'POST', body });
},
put<T>(url: string, body?: any, options?: RequestOptions): Promise<T> {
return fetchApi<T>(url, { ...options, method: 'PUT', body });
},
patch<T>(url: string, body?: any, options?: RequestOptions): Promise<T> {
return fetchApi<T>(url, { ...options, method: 'PATCH', body });
},
delete<T>(url: string, options?: RequestOptions): Promise<T> {
return fetchApi<T>(url, { ...options, method: 'DELETE' });
},
};
2 changes: 1 addition & 1 deletion apps/nextjs-app/src/lib/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { api } from './api-client';
// these are not part of features as this is a module shared across features

const getUser = async (): Promise<User> => {
const response = await api.get('/auth/me');
const response = (await api.get('/auth/me')) as { data: User };

return response.data;
};
Expand Down
11 changes: 1 addition & 10 deletions apps/nextjs-app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4066,15 +4066,6 @@ axe-core@^4.2.0, axe-core@^4.9.1:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59"
integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==

axios@^1.6.8:
version "1.7.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

axobject-query@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1"
Expand Down Expand Up @@ -6385,7 +6376,7 @@ flow-parser@0.*:
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.244.0.tgz#dc75ef468959ca72ad5fd89a6a9b0503c141ea8a"
integrity sha512-Dkc88m5k8bx1VvHTO9HEJ7tvMcSb3Zvcv1PY4OHK7pHdtdY2aUjhmPy6vpjVJ2uUUOIybRlb91sXE8g4doChtA==

follow-redirects@^1.14.0, follow-redirects@^1.15.6:
follow-redirects@^1.14.0:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
Expand Down

0 comments on commit 740e00f

Please sign in to comment.