Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/api/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type RouteParams = {

async function proxyToBackend(request: NextRequest, params: RouteParams) {
try {
const path = `/${(params.path ?? []).join('/')}`;
const path = `/api/${(params.path ?? []).join('/')}`;
const targetUrl = new URL(path + request.nextUrl.search, process.env.BACKEND_BASE_URL);

const proxyRequest = new Request(targetUrl, request);
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/auth/_authFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ type AuthFetchInit = RequestInit & {
};

export async function authFetch(path: string, init: AuthFetchInit = {}) {
const url = new URL(path, process.env.BACKEND_BASE_URL);
const url = new URL(`api/${path}`, process.env.BACKEND_BASE_URL);

const headers = new Headers(init.headers ?? {});

Expand Down
9 changes: 4 additions & 5 deletions src/app/api/auth/logout/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ export async function POST(request: NextRequest) {
},
});

if (!response.ok) {
const data = await response.json().catch(() => null);
return NextResponse.json(data ?? { message: 'Logout failed' }, { status: response.status });
}
const res = response.ok
? NextResponse.json({ ok: true })
: NextResponse.json({ message: 'Logout failed' }, { status: response.status });

const res = NextResponse.json({ ok: true });
// 백엔드 응답과 무관하게 쿠키는 항상 삭제 (토큰 만료 상태에서도 로그아웃 가능하도록)
res.cookies.delete({ name: ACCESS_TOKEN_KEY, path: '/' });
res.cookies.delete({ name: REFRESH_TOKEN_KEY, path: '/' });
return res;
Expand Down
2 changes: 1 addition & 1 deletion src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export async function middleware(request: NextRequest) {
const accessTokenValue = getAccessTokenFromCookies(request);

const response = await fetch(
new URL(`${API_URL.LESSON_DETAIL}/${lessonId}`, process.env.NEXT_PUBLIC_DEV_BASE_URL),
new URL(`api/${API_URL.LESSON_DETAIL}/${lessonId}`, process.env.NEXT_PUBLIC_DEV_BASE_URL),
{
method: 'GET',
headers: {
Expand Down
5 changes: 4 additions & 1 deletion src/shared/apis/kyInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { afterResponse } from '@/shared/apis/afterResponse';
const getPrefixUrl = (): string => {
if (isServer) {
const base = process.env.BACKEND_BASE_URL;
if (base) return base.endsWith('/') ? base.slice(0, -1) : base;
if (base) {
const normalized = base.endsWith('/') ? base.slice(0, -1) : base;
return `${normalized}/api`;
}
}
return '/api';
};
Expand Down
94 changes: 47 additions & 47 deletions src/shared/constants/apiURL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,66 @@ import type { LessonStatus } from '@/app/my/(instructor)/manage-classes/types/le
import type { ReservationStatus } from '@/app/my/(student)/classes/types/reservationStatus';

export const API_URL = {
AUTH_LOGIN: 'api/v1/auth/login',
AUTH_REISSUE: 'api/v1/auth/reissue',
AUTH_LOGOUT: 'api/v1/auth/logout',
AUTH_PHONE_REQUEST: 'api/v1/auth/phone/request',
AUTH_PHONE_VERIFY: 'api/v1/auth/phone/verify',
AUTH_LOGIN: 'v1/auth/login',
AUTH_REISSUE: 'v1/auth/reissue',
AUTH_LOGOUT: 'v1/auth/logout',
AUTH_PHONE_REQUEST: 'v1/auth/phone/request',
AUTH_PHONE_VERIFY: 'v1/auth/phone/verify',

MEMBERS_VALIDATE_WITHDRAW: 'api/v1/auth/validate-withdraw',
MEMBERS_WITHDRAW: 'api/v1/auth/withdraw',
MEMBERS_ONBOARD: 'api/v1/members/onboard',
MEMBERS_ME: 'api/v1/members/me',
MEMBERS_VALIDATE_WITHDRAW: 'v1/auth/validate-withdraw',
MEMBERS_WITHDRAW: 'v1/auth/withdraw',
MEMBERS_ONBOARD: 'v1/members/onboard',
MEMBERS_ME: 'v1/members/me',
MEMBERS_RESERVATIONS: (status: ReservationStatus) => {
return status === 'ALL' ? 'api/v1/members/me/reservations' : `api/v1/members/me/reservations?status=${status}`;
return status === 'ALL' ? 'v1/members/me/reservations' : `v1/members/me/reservations?status=${status}`;
},
MEMBERS_RESERVATIONS_CLASS_CARD: 'api/v1/members/me/reservations/{reservationId}/class-card',
MEMBERS_RESERVATIONS_CANCEL: 'api/v1/members/me/reservations/{reservationId}/cancel',
MEMBERS_RESERVATIONS_STATISTICS: 'api/v1/members/me/reservations/statistics',
MEMBERS_RESERVATION_DETAIL: 'api/v1/members/me/reservations',
MEMBERS_RESERVATIONS_CLASS_CARD: 'v1/members/me/reservations/{reservationId}/class-card',
MEMBERS_RESERVATIONS_CANCEL: 'v1/members/me/reservations/{reservationId}/cancel',
MEMBERS_RESERVATIONS_STATISTICS: 'v1/members/me/reservations/statistics',
MEMBERS_RESERVATION_DETAIL: 'v1/members/me/reservations',

TEACHERS: 'api/v1/teachers',
TEACHER_DETAIL: 'api/v1/teachers',
TEACHERS_ME: 'api/v1/teachers/me',
TEACHERS_LESSONS_DETAIL: 'api/v1/teachers/me/lessons',
TEACHERS: 'v1/teachers',
TEACHER_DETAIL: 'v1/teachers',
TEACHERS_ME: 'v1/teachers/me',
TEACHERS_LESSONS_DETAIL: 'v1/teachers/me/lessons',
TEACHERS_LESSONS: (status: LessonStatus) => {
return status === 'ALL' ? 'api/v1/teachers/me/lessons' : `api/v1/teachers/me/lessons?status=${status}`;
return status === 'ALL' ? 'v1/teachers/me/lessons' : `v1/teachers/me/lessons?status=${status}`;
},
TEACHER_DETAIL_INTRODUCTION: 'api/v1/teachers/me/detail',
TEACHER_ME_THUMBNAILS: 'api/v1/teachers/me/lessons/thumbnails',
TEACHER_ME_ACCOUNT: 'api/v1/teachers/me/account',
TEACHERS_POPULAR: 'api/v1/teachers/popular',
TEACHERS_SEARCH: 'api/v1/teachers?keyword=:keyword',
TEACHERS_LESSON_STATUS: 'api/v1/teachers/me/lessons/status',
TEACHER_DETAIL_INTRODUCTION: 'v1/teachers/me/detail',
TEACHER_ME_THUMBNAILS: 'v1/teachers/me/lessons/thumbnails',
TEACHER_ME_ACCOUNT: 'v1/teachers/me/account',
TEACHERS_POPULAR: 'v1/teachers/popular',
TEACHERS_SEARCH: 'v1/teachers?keyword=:keyword',
TEACHERS_LESSON_STATUS: 'v1/teachers/me/lessons/status',
TEACHERS_LESSON_CHANGE_APPROVE: (lessonId: number, reservationId: number) =>
`api/v1/teachers/me/lessons/${lessonId}/${reservationId}/change-approve`,
`v1/teachers/me/lessons/${lessonId}/${reservationId}/change-approve`,
TEACHERS_LESSON_CHANGE_CANCEL: (lessonId: number, reservationId: number) =>
`api/v1/teachers/me/lessons/${lessonId}/${reservationId}/change-cancel`,
TEACHER_NICKNAME_VALIDATION: 'api/v1/teachers/nickname-validation',
`v1/teachers/me/lessons/${lessonId}/${reservationId}/change-cancel`,
TEACHER_NICKNAME_VALIDATION: 'v1/teachers/nickname-validation',

LESSONS: 'api/v1/lessons',
LESSON_DETAIL: 'api/v1/lessons',
LESSON_UPDATE: 'api/v1/lessons',
LESSONS_LATEST: 'api/v1/lessons/latest',
LESSONS_POPULAR_GENRES: 'api/v1/lessons/popular-genres',
LESSONS_UPCOMING: 'api/v1/lessons/upcoming',
LESSONS_FAVORITES: 'api/v1/lessons/favorites/{lessonId}',
LESSON_RESERVE_PROGRESS: 'api/v1/lessons',
LESSON_RESERVATION: 'api/v2/lessons',
LESSON_RESERVATION_STATUS: 'api/v1/members/me/reservations/status',
LESSONS: 'v1/lessons',
LESSON_DETAIL: 'v1/lessons',
LESSON_UPDATE: 'v1/lessons',
LESSONS_LATEST: 'v1/lessons/latest',
LESSONS_POPULAR_GENRES: 'v1/lessons/popular-genres',
LESSONS_UPCOMING: 'v1/lessons/upcoming',
LESSONS_FAVORITES: 'v1/lessons/favorites/{lessonId}',
LESSON_RESERVE_PROGRESS: 'v1/lessons',
LESSON_RESERVATION: 'v2/lessons',
LESSON_RESERVATION_STATUS: 'v1/members/me/reservations/status',

MY_PAGE_FAVORITES: 'api/v1/mypage/favorites',
MY_PAGE_LESSONS: 'api/v1/mypage/lessons',
MY_PAGE_LESSON_DETAIL: 'api/v1/mypage/lessons/{lessonId}',
MY_PAGE_FAVORITES: 'v1/mypage/favorites',
MY_PAGE_LESSONS: 'v1/mypage/lessons',
MY_PAGE_LESSON_DETAIL: 'v1/mypage/lessons/{lessonId}',

ADVERTISEMENTS: 'api/v1/advertisements',
BANKS: 'api/v1/bank',
ADVERTISEMENTS: 'v1/advertisements',
BANKS: 'v1/bank',

SEARCH_LESSONS:
'api/v1/lessons?genre=:genre&level=:level&startDate=:startDate&endDate=:endDate&sortOption=:sortOption&keyword=:keyword',
'v1/lessons?genre=:genre&level=:level&startDate=:startDate&endDate=:endDate&sortOption=:sortOption&keyword=:keyword',

LOCATIONS: 'api/v1/locations',
LOCATIONS: 'v1/locations',

AUTH_ROLE: 'api/v1/auth/role',
IMAGES: 'api/v1/images',
AUTH_ROLE: 'v1/auth/role',
IMAGES: 'v1/images',
};
Loading