mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 07:36:23 +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;
|
keepalive_timeout 65;
|
||||||
types_hash_max_size 2048;
|
types_hash_max_size 2048;
|
||||||
|
|
||||||
|
# 헤더 및 쿠키 버퍼 크기 증가
|
||||||
|
large_client_header_buffers 4 32k;
|
||||||
|
client_header_buffer_size 32k;
|
||||||
|
|
||||||
gzip on;
|
gzip on;
|
||||||
gzip_vary on;
|
gzip_vary on;
|
||||||
gzip_proxied any;
|
gzip_proxied any;
|
||||||
@ -59,6 +63,11 @@ http {
|
|||||||
proxy_connect_timeout 180s;
|
proxy_connect_timeout 180s;
|
||||||
proxy_send_timeout 180s;
|
proxy_send_timeout 180s;
|
||||||
proxy_read_timeout 180s;
|
proxy_read_timeout 180s;
|
||||||
|
|
||||||
|
# 프록시 버퍼 크기 증가
|
||||||
|
proxy_buffer_size 32k;
|
||||||
|
proxy_buffers 4 32k;
|
||||||
|
proxy_busy_buffers_size 64k;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Static files
|
# Static files
|
||||||
|
|||||||
@ -25,11 +25,6 @@ const nextConfig = {
|
|||||||
source: '/api/v1/events/:path*',
|
source: '/api/v1/events/:path*',
|
||||||
destination: 'http://localhost:8080/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 {
|
import type {
|
||||||
ApiResponse,
|
ApiResponse,
|
||||||
PageResponse,
|
PageResponse,
|
||||||
@ -10,18 +10,19 @@ import type {
|
|||||||
/**
|
/**
|
||||||
* Participation API Service
|
* Participation API Service
|
||||||
* 이벤트 참여 관련 API 함수들
|
* 이벤트 참여 관련 API 함수들
|
||||||
|
* Next.js API Routes를 통해 프록시하여 CORS 문제 해결
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 참여 신청
|
* 이벤트 참여 신청
|
||||||
* POST /v1/events/{eventId}/participate
|
* POST /api/v1/events/{eventId}/participate
|
||||||
*/
|
*/
|
||||||
export const participate = async (
|
export const participate = async (
|
||||||
eventId: string,
|
eventId: string,
|
||||||
data: ParticipationRequest
|
data: ParticipationRequest
|
||||||
): Promise<ApiResponse<ParticipationResponse>> => {
|
): Promise<ApiResponse<ParticipationResponse>> => {
|
||||||
const response = await participationClient.post<ApiResponse<ParticipationResponse>>(
|
const response = await axios.post<ApiResponse<ParticipationResponse>>(
|
||||||
`/v1/events/${eventId}/participate`,
|
`/api/v1/events/${eventId}/participate`,
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
return response.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 (
|
export const getParticipants = async (
|
||||||
params: GetParticipantsParams
|
params: GetParticipantsParams
|
||||||
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
|
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
|
||||||
const { eventId, storeVisited, page = 0, size = 20, sort = ['createdAt,DESC'] } = params;
|
const { eventId, storeVisited, page = 0, size = 20, sort = ['createdAt,DESC'] } = params;
|
||||||
|
|
||||||
const response = await participationClient.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
const response = await axios.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
||||||
`/v1/events/${eventId}/participants`,
|
`/api/v1/events/${eventId}/participants`,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
storeVisited,
|
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 (
|
export const getParticipant = async (
|
||||||
eventId: string,
|
eventId: string,
|
||||||
participantId: string
|
participantId: string
|
||||||
): Promise<ApiResponse<ParticipationResponse>> => {
|
): Promise<ApiResponse<ParticipationResponse>> => {
|
||||||
const response = await participationClient.get<ApiResponse<ParticipationResponse>>(
|
const response = await axios.get<ApiResponse<ParticipationResponse>>(
|
||||||
`/v1/events/${eventId}/participants/${participantId}`
|
`/api/v1/events/${eventId}/participants/${participantId}`
|
||||||
);
|
);
|
||||||
return response.data;
|
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 (
|
export const drawWinners = async (
|
||||||
eventId: string,
|
eventId: string,
|
||||||
winnerCount: number,
|
winnerCount: number,
|
||||||
applyStoreVisitBonus?: boolean
|
applyStoreVisitBonus?: boolean
|
||||||
): Promise<ApiResponse<import('../types/api.types').DrawWinnersResponse>> => {
|
): Promise<ApiResponse<import('../types/api.types').DrawWinnersResponse>> => {
|
||||||
const response = await participationClient.post<ApiResponse<import('../types/api.types').DrawWinnersResponse>>(
|
const response = await axios.post<ApiResponse<import('../types/api.types').DrawWinnersResponse>>(
|
||||||
`/v1/events/${eventId}/draw-winners`,
|
`/api/v1/events/${eventId}/draw-winners`,
|
||||||
{
|
{
|
||||||
winnerCount,
|
winnerCount,
|
||||||
applyStoreVisitBonus,
|
applyStoreVisitBonus,
|
||||||
@ -131,7 +132,7 @@ export const drawWinners = async (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 당첨자 목록 조회
|
* 당첨자 목록 조회
|
||||||
* GET /v1/events/{eventId}/winners
|
* GET /api/v1/events/{eventId}/winners
|
||||||
*/
|
*/
|
||||||
export const getWinners = async (
|
export const getWinners = async (
|
||||||
eventId: string,
|
eventId: string,
|
||||||
@ -139,8 +140,8 @@ export const getWinners = async (
|
|||||||
size = 20,
|
size = 20,
|
||||||
sort: string[] = ['winnerRank,ASC']
|
sort: string[] = ['winnerRank,ASC']
|
||||||
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
|
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
|
||||||
const response = await participationClient.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
const response = await axios.get<ApiResponse<PageResponse<ParticipationResponse>>>(
|
||||||
`/v1/events/${eventId}/winners`,
|
`/api/v1/events/${eventId}/winners`,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
page,
|
page,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user