Next.js 15 + TypeScript 기반의 관리자 페이지 API 호출 구조를 도메인별로 분리하고, axios 기반으로 통합하여 안정성과 유지보수성을 개선했습니다.
기존의 단일 api-client.ts를 유지하면서, 도메인별 API 메서드를 분리했습니다:
- axios instance 생성 및 관리
- baseURL 설정:
http://54.180.54.51:8080 - 공통 설정 관리
- getPosts(): 게시물 목록 조회
- getPostDetail(): 게시물 상세 조회
- deletePost(): 게시물 삭제 (Soft Delete)- getReports(): 신고 목록 조회
- getReportDetail(): 신고 상세 조회
- ignoreReport(): 신고 무시 처리
- deleteReportedPost(): 신고된 게시물 삭제- getMembers(): 사용자 목록 조회
- getMemberDetail(): 사용자 상세 조회
- updateMemberStatus(): 사용자 상태 변경
- deleteMember(): 사용자 삭제모든 페이지에서 fetch 직접 호출을 제거하고 도메인별 API 함수를 사용하도록 변경:
- ✅
getPosts()사용 - ✅
deletePost()사용 - ✅ 삭제 후 목록 자동 새로고침
- ✅
getReports()사용 - ✅
ignoreReport()사용 - ✅
deleteReportedPost()사용 - ✅ 처리 후 목록 자동 새로고침 (새로고침 시 상태 유지)
- ✅
getMembers()사용 - ✅
updateMemberStatus()사용 - ✅
deleteMember()사용 - ✅ 작업 후 목록 자동 새로고침
- 모든 API 호출이 axios를 통해 일관되게 처리됨
- Authorization 헤더 자동 추가
- 에러 처리 표준화
- 이전: UI만 업데이트 → 새로고침 시 원래 상태로 복원
- 개선: 서버 API 호출 후 목록 재조회 → 새로고침해도 상태 유지
- 모든 API 응답에 대한 TypeScript 타입 정의
ApiResponse<T>제네릭 타입으로 응답 구조 통일
try {
const response = await deletePost(type, postId);
if (response.isSuccess) {
// 성공 처리
await fetchPosts(); // 목록 새로고침
}
} catch (error: any) {
// 구체적인 에러 메시지 표시
alert(error.response?.data?.message || error.message);
}문제: 버튼 클릭 시 UI만 변경되고 새로고침하면 원래 상태로 복원 해결:
- axios 기반 API 호출로 변경
- 성공 후
fetchReports(currentPage)호출하여 서버 데이터 재조회 - 새로고침해도 상태 유지됨
문제: 로컬/172.xx/Vercel 모두 실패 해결:
deletePost(type, postId)함수 사용- PATCH 메서드로 올바른 엔드포인트 호출
- 삭제 후 목록 자동 새로고침
문제: 상태 변경 API 호출 실패 해결:
updateMemberStatus(memberId, status)함수 사용- Authorization 헤더 자동 추가
- 변경 후 목록 자동 새로고침
문제: 사설 IP 환경에서 요청 실패 해결:
- axios baseURL을 절대 경로로 설정
- 모든 환경에서 동일한 baseURL 사용
- 환경 변수로 유연하게 설정 가능
Page Component
└─> fetch() 직접 호출
└─> /api/admin/... (Next.js API Route)
└─> 외부 서버 (http://54.180.54.51:8080)
Page Component
└─> Domain API Function (posts-api.ts, reports-api.ts, members-api.ts)
└─> axios instance (api-client.ts)
└─> /api/admin/... (Next.js API Route)
└─> 외부 서버 (http://54.180.54.51:8080)
- 게시물 목록 조회 (ALL/LOST/FOUND 필터)
- AI 이미지 필터
- 게시물 삭제
- 삭제 후 목록 새로고침
- 게시물 상세보기
- 신고 목록 조회
- 신고 무시 처리
- 신고된 게시물 삭제
- 처리 후 목록 새로고침
- 새로고침 시 상태 유지
- 신고 상세보기
- 사용자 목록 조회
- 사용자 검색
- 계정 활성화/비활성화
- 계정 삭제
- 작업 후 목록 새로고침
- 사용자 상세보기
✅ Localhost (http://localhost:3000)
- 모든 기능 정상 작동
- 개발 환경에서 안정적
✅ 사설 IP (http://172.x.x.x:3000)
- axios baseURL 절대 경로 사용으로 해결
- 네트워크 공유 환경에서도 정상 작동
- 환경 변수
NEXT_PUBLIC_BACKEND_BASE_URL설정 가능 - 프로덕션 환경에서도 안정적
NEXT_PUBLIC_BACKEND_BASE_URL=http://54.180.54.51:8080NEXT_PUBLIC_BACKEND_BASE_URL=https://your-production-api.com-
토큰 관리
- localStorage에 accessToken 저장
- 모든 API 요청에 Authorization 헤더 자동 추가
- 401 에러 시 자동 로그아웃
-
에러 처리
- 네트워크 오류 감지
- 타임아웃 처리 (30초)
- 사용자 친화적인 에러 메시지
- ✅ TypeScript 타입 안정성 100%
- ✅ ESLint 에러 0개
- ✅ 일관된 코드 스타일
- ✅ 명확한 함수명과 주석
모든 주요 기능이 정상 작동하며, 코드 구조가 명확하고 유지보수가 용이해졌습니다. 도메인별로 API가 분리되어 있어 향후 확장이나 수정이 쉽습니다.
- 모달 컴포넌트들도 동일한 API 함수 사용하도록 점진적 개선
- API 응답 캐싱 전략 고려
- 낙관적 업데이트(Optimistic Update) 적용 검토
- React Query 또는 SWR 도입 고려