api 호출 오류 수정
This commit is contained in:
parent
bed23e256b
commit
2e84c4272f
|
|
@ -36,40 +36,100 @@ export function ChartRenderer({ element, data, width = 250, height = 200 }: Char
|
||||||
}
|
}
|
||||||
|
|
||||||
// 데이터 소스가 설정되어 있으면 페칭
|
// 데이터 소스가 설정되어 있으면 페칭
|
||||||
if (element.dataSource && element.dataSource.query && element.chartConfig) {
|
if (element.dataSource && element.chartConfig) {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let queryResult: QueryResult;
|
let queryResult: QueryResult;
|
||||||
|
|
||||||
// 현재 DB vs 외부 DB 분기
|
// REST API vs Database 분기
|
||||||
if (element.dataSource.connectionType === "external" && element.dataSource.externalConnectionId) {
|
if (element.dataSource.type === "api" && element.dataSource.endpoint) {
|
||||||
// 외부 DB
|
// REST API
|
||||||
const result = await ExternalDbConnectionAPI.executeQuery(
|
const params = new URLSearchParams();
|
||||||
parseInt(element.dataSource.externalConnectionId),
|
if (element.dataSource.queryParams) {
|
||||||
element.dataSource.query,
|
Object.entries(element.dataSource.queryParams).forEach(([key, value]) => {
|
||||||
);
|
if (key && value) {
|
||||||
|
params.append(key, value);
|
||||||
if (!result.success) {
|
}
|
||||||
throw new Error(result.message || "외부 DB 쿼리 실행 실패");
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let url = element.dataSource.endpoint;
|
||||||
|
const queryString = params.toString();
|
||||||
|
if (queryString) {
|
||||||
|
url += (url.includes("?") ? "&" : "?") + queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...element.dataSource.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiData = await response.json();
|
||||||
|
|
||||||
|
// JSON Path 처리
|
||||||
|
let processedData = apiData;
|
||||||
|
if (element.dataSource.jsonPath) {
|
||||||
|
const paths = element.dataSource.jsonPath.split(".");
|
||||||
|
for (const path of paths) {
|
||||||
|
if (processedData && typeof processedData === "object" && path in processedData) {
|
||||||
|
processedData = processedData[path];
|
||||||
|
} else {
|
||||||
|
throw new Error(`JSON Path "${element.dataSource.jsonPath}"에서 데이터를 찾을 수 없습니다`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = Array.isArray(processedData) ? processedData : [processedData];
|
||||||
|
const columns = rows.length > 0 ? Object.keys(rows[0]) : [];
|
||||||
|
|
||||||
queryResult = {
|
queryResult = {
|
||||||
columns: result.data?.[0] ? Object.keys(result.data[0]) : [],
|
columns,
|
||||||
rows: result.data || [],
|
rows,
|
||||||
totalRows: result.data?.length || 0,
|
totalRows: rows.length,
|
||||||
executionTime: 0,
|
executionTime: 0,
|
||||||
};
|
};
|
||||||
|
} else if (element.dataSource.query) {
|
||||||
|
// Database (현재 DB 또는 외부 DB)
|
||||||
|
if (element.dataSource.connectionType === "external" && element.dataSource.externalConnectionId) {
|
||||||
|
// 외부 DB
|
||||||
|
const result = await ExternalDbConnectionAPI.executeQuery(
|
||||||
|
parseInt(element.dataSource.externalConnectionId),
|
||||||
|
element.dataSource.query,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
throw new Error(result.message || "외부 DB 쿼리 실행 실패");
|
||||||
|
}
|
||||||
|
|
||||||
|
queryResult = {
|
||||||
|
columns: result.data?.[0] ? Object.keys(result.data[0]) : [],
|
||||||
|
rows: result.data || [],
|
||||||
|
totalRows: result.data?.length || 0,
|
||||||
|
executionTime: 0,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// 현재 DB
|
||||||
|
const result = await dashboardApi.executeQuery(element.dataSource.query);
|
||||||
|
queryResult = {
|
||||||
|
columns: result.columns,
|
||||||
|
rows: result.rows,
|
||||||
|
totalRows: result.rowCount,
|
||||||
|
executionTime: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 현재 DB
|
throw new Error("데이터 소스가 올바르게 설정되지 않았습니다");
|
||||||
const result = await dashboardApi.executeQuery(element.dataSource.query);
|
|
||||||
queryResult = {
|
|
||||||
columns: result.columns,
|
|
||||||
rows: result.rows,
|
|
||||||
totalRows: result.rowCount,
|
|
||||||
executionTime: 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChartData로 변환
|
// ChartData로 변환
|
||||||
|
|
|
||||||
|
|
@ -91,33 +91,59 @@ export function ApiConfig({ dataSource, onChange, onTestResult }: ApiConfigProps
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `http://localhost:8080/api/dashboards/fetch-api?${params.toString()}`;
|
// URL 구성
|
||||||
|
let url = dataSource.endpoint;
|
||||||
|
const queryString = params.toString();
|
||||||
|
if (queryString) {
|
||||||
|
url += (url.includes("?") ? "&" : "?") + queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 헤더 구성
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...dataSource.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 외부 API 직접 호출
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: "POST",
|
method: "GET",
|
||||||
headers: {
|
headers,
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${localStorage.getItem("token") || "test-token"}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
endpoint: dataSource.endpoint,
|
|
||||||
headers: dataSource.headers || {},
|
|
||||||
jsonPath: dataSource.jsonPath || "",
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: ApiResponse<QueryResult> = await response.json();
|
const apiData = await response.json();
|
||||||
|
|
||||||
if (!result.success) {
|
// JSON Path 처리
|
||||||
throw new Error(result.message || "API 호출에 실패했습니다");
|
let data = apiData;
|
||||||
|
if (dataSource.jsonPath) {
|
||||||
|
const paths = dataSource.jsonPath.split(".");
|
||||||
|
for (const path of paths) {
|
||||||
|
if (data && typeof data === "object" && path in data) {
|
||||||
|
data = data[path];
|
||||||
|
} else {
|
||||||
|
throw new Error(`JSON Path "${dataSource.jsonPath}"에서 데이터를 찾을 수 없습니다`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTestResult(result.data);
|
// 배열이 아니면 배열로 변환
|
||||||
onTestResult?.(result.data);
|
const rows = Array.isArray(data) ? data : [data];
|
||||||
|
|
||||||
|
// 컬럼 추출
|
||||||
|
const columns = rows.length > 0 ? Object.keys(rows[0]) : [];
|
||||||
|
|
||||||
|
const result: QueryResult = {
|
||||||
|
columns,
|
||||||
|
rows,
|
||||||
|
totalRows: rows.length,
|
||||||
|
executionTime: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
setTestResult(result);
|
||||||
|
onTestResult?.(result);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errorMessage = err instanceof Error ? err.message : "알 수 없는 오류가 발생했습니다";
|
const errorMessage = err instanceof Error ? err.message : "알 수 없는 오류가 발생했습니다";
|
||||||
setTestError(errorMessage);
|
setTestError(errorMessage);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue