restapi 여러개 띄우는거 작업 가능하게 하는거 진행중

This commit is contained in:
leeheejin
2025-10-27 18:33:15 +09:00
parent 4f2cf6c0ff
commit 5b394473f4
23 changed files with 4283 additions and 106 deletions

View File

@@ -606,16 +606,32 @@ export class DashboardController {
}
});
// 외부 API 호출
// 외부 API 호출 (타임아웃 30초)
// @ts-ignore - node-fetch dynamic import
const fetch = (await import("node-fetch")).default;
const response = await fetch(urlObj.toString(), {
method: method.toUpperCase(),
headers: {
"Content-Type": "application/json",
...headers,
},
});
// 타임아웃 설정 (Node.js 글로벌 AbortController 사용)
const controller = new (global as any).AbortController();
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60초 (기상청 API는 느림)
let response;
try {
response = await fetch(urlObj.toString(), {
method: method.toUpperCase(),
headers: {
"Content-Type": "application/json",
...headers,
},
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (err: any) {
clearTimeout(timeoutId);
if (err.name === 'AbortError') {
throw new Error('외부 API 요청 타임아웃 (30초 초과)');
}
throw err;
}
if (!response.ok) {
throw new Error(
@@ -623,7 +639,40 @@ export class DashboardController {
);
}
const data = await response.json();
// Content-Type에 따라 응답 파싱
const contentType = response.headers.get("content-type");
let data: any;
// 한글 인코딩 처리 (EUC-KR → UTF-8)
const isKoreanApi = urlObj.hostname.includes('kma.go.kr') ||
urlObj.hostname.includes('data.go.kr');
if (isKoreanApi) {
// 한국 정부 API는 EUC-KR 인코딩 사용
const buffer = await response.arrayBuffer();
const decoder = new TextDecoder('euc-kr');
const text = decoder.decode(buffer);
try {
data = JSON.parse(text);
} catch {
data = { text, contentType };
}
} else if (contentType && contentType.includes("application/json")) {
data = await response.json();
} else if (contentType && contentType.includes("text/")) {
// 텍스트 응답 (CSV, 일반 텍스트 등)
const text = await response.text();
data = { text, contentType };
} else {
// 기타 응답 (JSON으로 시도)
try {
data = await response.json();
} catch {
const text = await response.text();
data = { text, contentType };
}
}
res.status(200).json({
success: true,

View File

@@ -28,7 +28,7 @@ export class ExternalRestApiConnectionService {
try {
let query = `
SELECT
id, connection_name, description, base_url, default_headers,
id, connection_name, description, base_url, endpoint_path, default_headers,
auth_type, auth_config, timeout, retry_count, retry_delay,
company_code, is_active, created_date, created_by,
updated_date, updated_by, last_test_date, last_test_result, last_test_message
@@ -110,7 +110,7 @@ export class ExternalRestApiConnectionService {
try {
const query = `
SELECT
id, connection_name, description, base_url, default_headers,
id, connection_name, description, base_url, endpoint_path, default_headers,
auth_type, auth_config, timeout, retry_count, retry_delay,
company_code, is_active, created_date, created_by,
updated_date, updated_by, last_test_date, last_test_result, last_test_message
@@ -167,10 +167,10 @@ export class ExternalRestApiConnectionService {
const query = `
INSERT INTO external_rest_api_connections (
connection_name, description, base_url, default_headers,
connection_name, description, base_url, endpoint_path, default_headers,
auth_type, auth_config, timeout, retry_count, retry_delay,
company_code, is_active, created_by
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
RETURNING *
`;
@@ -178,6 +178,7 @@ export class ExternalRestApiConnectionService {
data.connection_name,
data.description || null,
data.base_url,
data.endpoint_path || null,
JSON.stringify(data.default_headers || {}),
data.auth_type,
encryptedAuthConfig ? JSON.stringify(encryptedAuthConfig) : null,
@@ -261,6 +262,12 @@ export class ExternalRestApiConnectionService {
paramIndex++;
}
if (data.endpoint_path !== undefined) {
updateFields.push(`endpoint_path = $${paramIndex}`);
params.push(data.endpoint_path);
paramIndex++;
}
if (data.default_headers !== undefined) {
updateFields.push(`default_headers = $${paramIndex}`);
params.push(JSON.stringify(data.default_headers));

View File

@@ -41,7 +41,7 @@ export class RiskAlertService {
disp: 0,
authKey: apiKey,
},
timeout: 10000,
timeout: 30000, // 30초로 증가
responseType: 'arraybuffer', // 인코딩 문제 해결
});

View File

@@ -7,6 +7,7 @@ export interface ExternalRestApiConnection {
connection_name: string;
description?: string;
base_url: string;
endpoint_path?: string;
default_headers: Record<string, string>;
auth_type: AuthType;
auth_config?: {