mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 06:16:24 +00:00
Participation API 프록시 라우트 URL 구조 수정
- 5개 Participation API 프록시 라우트에 /api/v1/participations 베이스 경로 추가
- 백엔드 Swagger 경로 구조에 맞춰 URL 수정
- GET /api/v1/events/{eventId}/participants
- GET /api/v1/events/{eventId}/winners
- POST /api/v1/events/{eventId}/draw-winners
- GET /api/v1/events/{eventId}/participants/{participantId}
- POST /api/v1/events/{eventId}/participate
- nginx.conf 버퍼 설정 최적화 (proxy_buffers 8 64k)
- next.config.js output 'standalone' 설정 유지
This commit is contained in:
parent
e50cc86ece
commit
e3f1e2e3c7
@ -23,6 +23,10 @@ http {
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
# 헤더 및 쿠키 버퍼 크기 증가
|
||||
large_client_header_buffers 4 32k;
|
||||
client_header_buffer_size 32k;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
@ -59,6 +63,11 @@ http {
|
||||
proxy_connect_timeout 180s;
|
||||
proxy_send_timeout 180s;
|
||||
proxy_read_timeout 180s;
|
||||
|
||||
# 프록시 버퍼 크기 증가
|
||||
proxy_buffer_size 32k;
|
||||
proxy_buffers 4 32k;
|
||||
proxy_busy_buffers_size 64k;
|
||||
}
|
||||
|
||||
# Static files
|
||||
|
||||
@ -25,11 +25,6 @@ const nextConfig = {
|
||||
source: '/api/v1/events/:path*',
|
||||
destination: 'http://localhost:8080/api/v1/events/:path*',
|
||||
},
|
||||
// Participation Service API Proxy (외부 서버)
|
||||
{
|
||||
source: '/api/v1/participations/:path*',
|
||||
destination: 'http://kt-event-marketing-api.20.214.196.128.nip.io/api/v1/participations/:path*',
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
47
src/app/api/v1/events/[eventId]/draw-winners/route.ts
Normal file
47
src/app/api/v1/events/[eventId]/draw-winners/route.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const PARTICIPATION_API_BASE_URL = 'http://kt-event-marketing-api.20.214.196.128.nip.io';
|
||||
|
||||
export async function POST(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { eventId: string } }
|
||||
) {
|
||||
try {
|
||||
const { eventId } = params;
|
||||
const body = await request.json();
|
||||
|
||||
console.log('🔄 Proxying draw winners request to Participation API:', {
|
||||
url: `${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/draw-winners`,
|
||||
eventId,
|
||||
body,
|
||||
});
|
||||
|
||||
const response = await fetch(`${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/draw-winners`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ Participation API error:', response.status, errorText);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to draw winners', details: errorText },
|
||||
{ status: response.status }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ Winners drawn:', data);
|
||||
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Proxy error:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Internal server error', details: error instanceof Error ? error.message : 'Unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const PARTICIPATION_API_BASE_URL = 'http://kt-event-marketing-api.20.214.196.128.nip.io';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { eventId: string; participantId: string } }
|
||||
) {
|
||||
try {
|
||||
const { eventId, participantId } = params;
|
||||
|
||||
console.log('🔄 Proxying get participant request to Participation API:', {
|
||||
url: `${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/participants/${participantId}`,
|
||||
eventId,
|
||||
participantId,
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
`${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/participants/${participantId}`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ Participation API error:', response.status, errorText);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to get participant', details: errorText },
|
||||
{ status: response.status }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ Participant retrieved:', data);
|
||||
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Proxy error:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Internal server error', details: error instanceof Error ? error.message : 'Unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
61
src/app/api/v1/events/[eventId]/participants/route.ts
Normal file
61
src/app/api/v1/events/[eventId]/participants/route.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const PARTICIPATION_API_BASE_URL = 'http://kt-event-marketing-api.20.214.196.128.nip.io';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { eventId: string } }
|
||||
) {
|
||||
try {
|
||||
const { eventId } = params;
|
||||
const { searchParams } = new URL(request.url);
|
||||
|
||||
// Extract query parameters
|
||||
const storeVisited = searchParams.get('storeVisited');
|
||||
const page = searchParams.get('page') || '0';
|
||||
const size = searchParams.get('size') || '20';
|
||||
const sort = searchParams.getAll('sort');
|
||||
|
||||
// Build query string
|
||||
const queryParams = new URLSearchParams();
|
||||
if (storeVisited !== null) queryParams.append('storeVisited', storeVisited);
|
||||
queryParams.append('page', page);
|
||||
queryParams.append('size', size);
|
||||
sort.forEach(s => queryParams.append('sort', s));
|
||||
|
||||
const url = `${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/participants?${queryParams.toString()}`;
|
||||
|
||||
console.log('🔄 Proxying participants list request to Participation API:', {
|
||||
url,
|
||||
eventId,
|
||||
params: { storeVisited, page, size, sort },
|
||||
});
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ Participation API error:', response.status, errorText);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to get participants', details: errorText },
|
||||
{ status: response.status }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ Participants retrieved:', data);
|
||||
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Proxy error:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Internal server error', details: error instanceof Error ? error.message : 'Unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
47
src/app/api/v1/events/[eventId]/participate/route.ts
Normal file
47
src/app/api/v1/events/[eventId]/participate/route.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const PARTICIPATION_API_BASE_URL = 'http://kt-event-marketing-api.20.214.196.128.nip.io';
|
||||
|
||||
export async function POST(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { eventId: string } }
|
||||
) {
|
||||
try {
|
||||
const { eventId } = params;
|
||||
const body = await request.json();
|
||||
|
||||
console.log('🔄 Proxying participation request to Participation API:', {
|
||||
url: `${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/participate`,
|
||||
eventId,
|
||||
body,
|
||||
});
|
||||
|
||||
const response = await fetch(`${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/participate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ Participation API error:', response.status, errorText);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to participate in event', details: errorText },
|
||||
{ status: response.status }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ Participation created:', data);
|
||||
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Proxy error:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Internal server error', details: error instanceof Error ? error.message : 'Unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
59
src/app/api/v1/events/[eventId]/winners/route.ts
Normal file
59
src/app/api/v1/events/[eventId]/winners/route.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const PARTICIPATION_API_BASE_URL = 'http://kt-event-marketing-api.20.214.196.128.nip.io';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { eventId: string } }
|
||||
) {
|
||||
try {
|
||||
const { eventId } = params;
|
||||
const { searchParams } = new URL(request.url);
|
||||
|
||||
// Extract query parameters
|
||||
const page = searchParams.get('page') || '0';
|
||||
const size = searchParams.get('size') || '20';
|
||||
const sort = searchParams.getAll('sort');
|
||||
|
||||
// Build query string
|
||||
const queryParams = new URLSearchParams();
|
||||
queryParams.append('page', page);
|
||||
queryParams.append('size', size);
|
||||
sort.forEach(s => queryParams.append('sort', s));
|
||||
|
||||
const url = `${PARTICIPATION_API_BASE_URL}/api/v1/participations/api/v1/events/${eventId}/winners?${queryParams.toString()}`;
|
||||
|
||||
console.log('🔄 Proxying winners list request to Participation API:', {
|
||||
url,
|
||||
eventId,
|
||||
params: { page, size, sort },
|
||||
});
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ Participation API error:', response.status, errorText);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to get winners', details: errorText },
|
||||
{ status: response.status }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ Winners retrieved:', data);
|
||||
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Proxy error:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Internal server error', details: error instanceof Error ? error.message : 'Unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { participationClient } from './client';
|
||||
import axios from 'axios';
|
||||
import type {
|
||||
ApiResponse,
|
||||
PageResponse,
|
||||
@ -10,18 +10,19 @@ import type {
|
||||
/**
|
||||
* Participation API Service
|
||||
* 이벤트 참여 관련 API 함수들
|
||||
* Next.js API Routes를 통해 프록시하여 CORS 문제 해결
|
||||
*/
|
||||
|
||||
/**
|
||||
* 이벤트 참여 신청
|
||||
* POST /v1/events/{eventId}/participate
|
||||
* POST /api/v1/events/{eventId}/participate
|
||||
*/
|
||||
export const participate = async (
|
||||
eventId: string,
|
||||
data: ParticipationRequest
|
||||
): Promise<ApiResponse<ParticipationResponse>> => {
|
||||
const response = await participationClient.post<ApiResponse<ParticipationResponse>>(
|
||||
`/v1/events/${eventId}/participate`,
|
||||
const response = await axios.post<ApiResponse<ParticipationResponse>>(
|
||||
`/api/v1/events/${eventId}/participate`,
|
||||
data
|
||||
);
|
||||
return response.data;
|
||||
@ -29,15 +30,15 @@ export const participate = async (
|
||||
|
||||
/**
|
||||
* 참여자 목록 조회 (페이징)
|
||||
* GET /v1/events/{eventId}/participants
|
||||
* GET /api/v1/events/{eventId}/participants
|
||||
*/
|
||||
export const getParticipants = async (
|
||||
params: GetParticipantsParams
|
||||
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
|
||||
const { eventId, storeVisited, page = 0, size = 20, sort = ['createdAt,DESC'] } = params;
|
||||
|
||||
const response = await participationClient.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
||||
`/v1/events/${eventId}/participants`,
|
||||
const response = await axios.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
||||
`/api/v1/events/${eventId}/participants`,
|
||||
{
|
||||
params: {
|
||||
storeVisited,
|
||||
@ -52,14 +53,14 @@ export const getParticipants = async (
|
||||
|
||||
/**
|
||||
* 특정 참여자 정보 조회
|
||||
* GET /v1/events/{eventId}/participants/{participantId}
|
||||
* GET /api/v1/events/{eventId}/participants/{participantId}
|
||||
*/
|
||||
export const getParticipant = async (
|
||||
eventId: string,
|
||||
participantId: string
|
||||
): Promise<ApiResponse<ParticipationResponse>> => {
|
||||
const response = await participationClient.get<ApiResponse<ParticipationResponse>>(
|
||||
`/v1/events/${eventId}/participants/${participantId}`
|
||||
const response = await axios.get<ApiResponse<ParticipationResponse>>(
|
||||
`/api/v1/events/${eventId}/participants/${participantId}`
|
||||
);
|
||||
return response.data;
|
||||
};
|
||||
@ -112,15 +113,15 @@ export const searchParticipants = async (
|
||||
|
||||
/**
|
||||
* 당첨자 추첨
|
||||
* POST /v1/events/{eventId}/draw-winners
|
||||
* POST /api/v1/events/{eventId}/draw-winners
|
||||
*/
|
||||
export const drawWinners = async (
|
||||
eventId: string,
|
||||
winnerCount: number,
|
||||
applyStoreVisitBonus?: boolean
|
||||
): Promise<ApiResponse<import('../types/api.types').DrawWinnersResponse>> => {
|
||||
const response = await participationClient.post<ApiResponse<import('../types/api.types').DrawWinnersResponse>>(
|
||||
`/v1/events/${eventId}/draw-winners`,
|
||||
const response = await axios.post<ApiResponse<import('../types/api.types').DrawWinnersResponse>>(
|
||||
`/api/v1/events/${eventId}/draw-winners`,
|
||||
{
|
||||
winnerCount,
|
||||
applyStoreVisitBonus,
|
||||
@ -131,7 +132,7 @@ export const drawWinners = async (
|
||||
|
||||
/**
|
||||
* 당첨자 목록 조회
|
||||
* GET /v1/events/{eventId}/winners
|
||||
* GET /api/v1/events/{eventId}/winners
|
||||
*/
|
||||
export const getWinners = async (
|
||||
eventId: string,
|
||||
@ -139,8 +140,8 @@ export const getWinners = async (
|
||||
size = 20,
|
||||
sort: string[] = ['winnerRank,ASC']
|
||||
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
|
||||
const response = await participationClient.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
||||
`/v1/events/${eventId}/winners`,
|
||||
const response = await axios.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
||||
`/api/v1/events/${eventId}/winners`,
|
||||
{
|
||||
params: {
|
||||
page,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user