15 KiB
15 KiB
🌐 제어관리 외부호출 REST API 기능 구현 계획서
📋 프로젝트 개요
목적
제어관리 시스템에서 관계 생성 시 연결타입으로 "외부호출"을 선택하면 REST API 호출 기능을 설정할 수 있도록 구현합니다.
현재 상황 분석
기존 연결타입 구조
- 데이터 저장: INSERT/UPDATE/DELETE 작업 지원
- 외부 호출: 기본 구조는 있으나 REST API 전용 설정 UI 필요
기존 외부호출 기능
ExternalCallSettings.tsx: 복합적인 외부호출 설정 (REST API, 이메일, FTP, 큐)SimpleExternalCallSettings.tsx: 기존 설정을 재사용하는 단순화된 버전ExternalCallAPI: REST API 테스트/실행 기능 완료ExternalCallService: 백엔드 로직 완료
🎯 구현 목표
1단계: REST API 전용 설정 컴포넌트 개발
기존 복합 설정에서 REST API 부분만 추출하여 전용 컴포넌트 생성
2단계: 연결타입 선택 시 REST API 설정 연동
ConnectionTypeSelector에서 "외부호출" 선택 시 REST API 설정 패널 표시
3단계: 설정 저장 및 실행 로직 연동
관계 데이터에 REST API 설정 저장 및 실행 시점 연동
🏗️ 시스템 아키텍처 설계
1. 분리된 외부호출 컴포넌트 구조
🔄 설계 철학: 완전 분리형 아키텍처
기존 데이터 저장 기능과 완전히 독립된 외부호출 전용 컴포넌트들을 구성하여 각각의 책임을 명확히 분리합니다.
ExternalCallPanel.tsx (신규 생성 - 메인 패널)
interface ExternalCallPanelProps {
relationshipId: string;
onSettingsChange: (settings: ExternalCallConfig) => void;
initialSettings?: ExternalCallConfig;
}
// 외부호출 전용 설정 구조
interface ExternalCallConfig {
callType: "rest-api"; // 향후 확장 가능
restApiSettings: RestApiSettings;
}
RestApiSettings.tsx (신규 생성 - REST API 전용)
interface RestApiSettingsProps {
settings: RestApiSettings;
onSettingsChange: (settings: RestApiSettings) => void;
}
interface RestApiSettings {
apiUrl: string;
httpMethod: "GET" | "POST" | "PUT" | "DELETE";
headers: Record<string, string>;
bodyTemplate: string;
authentication?: {
type: "none" | "bearer" | "basic" | "api-key";
token?: string;
username?: string;
password?: string;
apiKey?: string;
apiKeyHeader?: string;
};
timeout?: number;
retryCount?: number;
}
ExternalCallTestPanel.tsx (신규 생성 - 테스트 전용)
interface ExternalCallTestPanelProps {
settings: RestApiSettings;
onTestResult: (result: TestResult) => void;
}
주요 기능
- URL 설정: API 엔드포인트 URL 입력
- HTTP 메서드: GET, POST, PUT, DELETE 선택
- 헤더 설정: Content-Type, Authorization 등 커스텀 헤더
- 바디 템플릿: POST/PUT 요청 시 JSON 바디 템플릿
- 인증 설정: Bearer Token, Basic Auth, API Key 지원
- 고급 설정: 타임아웃, 재시도 횟수
- 테스트 기능: 설정한 API 실제 호출 테스트
2. 연결타입 선택 플로우 개선
ConnectionTypeSelector 수정
// 기존 코드 유지, 외부호출 선택 시 이벤트 처리만 추가
const connectionTypes: ConnectionType[] = [
{
id: "data_save",
label: "데이터 저장",
description: "INSERT/UPDATE/DELETE 작업",
icon: <Database className="h-4 w-4" />,
},
{
id: "external_call",
label: "외부 호출",
description: "REST API 호출", // 설명 업데이트
icon: <Globe className="h-4 w-4" />,
},
];
ConnectionSetupModal 수정
// 외부호출 선택 시 완전 분리된 ExternalCallPanel 표시
{
selectedConnectionType === "external_call" && (
<ExternalCallPanel
relationshipId={relationshipId}
initialSettings={externalCallConfig}
onSettingsChange={setExternalCallConfig}
/>
);
}
// 데이터 저장 선택 시 기존 DataSavePanel 표시
{
selectedConnectionType === "data_save" && (
<DataSavePanel
relationshipId={relationshipId}
initialSettings={dataSaveConfig}
onSettingsChange={setDataSaveConfig}
/>
);
}
3. 데이터 구조 확장
관계 데이터 스키마 확장
-- relationships 테이블에 rest_api_settings 컬럼 추가 (JSON 타입)
ALTER TABLE relationships
ADD COLUMN rest_api_settings JSONB;
-- 인덱스 추가 (성능 최적화)
CREATE INDEX idx_relationships_rest_api_settings
ON relationships USING GIN (rest_api_settings);
TypeScript 타입 정의
// types/connectionTypes.ts 확장
export interface RelationshipData {
id: string;
sourceNodeId: string;
targetNodeId: string;
connectionType: "data_save" | "external_call";
// 기존 필드들...
dataSaveSettings?: DataSaveSettings;
// 새로 추가
restApiSettings?: RestApiSettings;
}
📱 UI/UX 설계
1. REST API 설정 패널 레이아웃
┌─────────────────────────────────────────────────────────┐
│ 🌐 REST API 설정 [테스트] 버튼 │
├─────────────────────────────────────────────────────────┤
│ API URL │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ https://api.example.com/webhook │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ HTTP 메서드 │ 인증 방식 │
│ ┌─────────────┐ │ ┌─────────────────────────────────┐ │
│ │ POST ▼ │ │ │ Bearer Token ▼ │ │
│ └─────────────┘ │ └─────────────────────────────────┘ │
│ │
│ 헤더 설정 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Content-Type: application/json │ │
│ │ Authorization: Bearer {token} │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 요청 바디 템플릿 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ { │ │
│ │ "message": "{{message}}", │ │
│ │ "data": {{sourceData}}, │ │
│ │ "timestamp": "{{timestamp}}" │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 고급 설정 │
│ 타임아웃: [30] 초 재시도: [3] 회 │
└─────────────────────────────────────────────────────────┘
2. 템플릿 변수 지원
사용 가능한 템플릿 변수
{{sourceData}}: 소스 노드의 전체 데이터{{targetData}}: 타겟 노드의 데이터 (있는 경우){{timestamp}}: 현재 타임스탬프{{relationshipId}}: 관계 ID{{diagramId}}: 다이어그램 ID{{userId}}: 현재 사용자 ID
템플릿 도우미 UI
const TemplateHelper = () => (
<div className="text-xs text-gray-600 mt-2">
<details>
<summary className="cursor-pointer">사용 가능한 템플릿 변수</summary>
<div className="mt-2 space-y-1">
<div>
<code>{"{{sourceData}}"}</code> - 소스 노드 데이터
</div>
<div>
<code>{"{{timestamp}}"}</code> - 현재 시간
</div>
<div>
<code>{"{{relationshipId}}"}</code> - 관계 ID
</div>
</div>
</details>
</div>
);
🔧 구현 단계별 계획
Phase 1: 기본 REST API 설정 컴포넌트 (1-2일)
1.1 분리된 컴포넌트 구조 생성
- ExternalCallPanel.tsx: 외부호출 메인 패널 컴포넌트
- RestApiSettings.tsx: REST API 전용 설정 컴포넌트
- ExternalCallTestPanel.tsx: API 테스트 전용 컴포넌트
- 외부호출 전용 디렉토리:
components/dataflow/external-call/생성
1.2 타입 정의 분리
- ExternalCallTypes.ts: 외부호출 전용 타입 정의 파일 생성
- RestApiTypes.ts: REST API 전용 타입 정의
- 기존
connectionTypes.ts와 완전 분리하여 독립성 확보
Phase 2: 연결타입 선택 연동 (1일)
2.1 ConnectionSetupModal 수정
- 외부호출 선택 시 RestApiSettings 컴포넌트 표시
- 상태 관리 로직 추가
- 설정 저장/불러오기 연동
2.2 ConnectionTypeSelector 설명 업데이트
- 외부호출 설명을 "REST API 호출"로 명확화
Phase 3: 인증 및 고급 기능 (2-3일)
3.1 인증 방식 지원
- Bearer Token 인증
- Basic Authentication
- API Key 인증 (헤더/쿼리 파라미터)
- 인증 정보 암호화 저장
3.2 고급 설정
- 타임아웃 설정
- 재시도 로직
- 응답 검증 규칙
Phase 4: 테스트 및 실행 기능 (1-2일)
4.1 테스트 기능 구현
- 설정한 API 실제 호출 테스트
- 응답 결과 표시
- 오류 메시지 상세 표시
4.2 실행 로직 연동
- 관계 실행 시 REST API 호출
- 템플릿 변수 치환
- 실행 결과 로깅
Phase 5: 템플릿 시스템 고도화 (2-3일)
5.1 템플릿 변수 확장
- 소스/타겟 데이터 접근
- 조건부 템플릿 (if/else)
- 반복 템플릿 (for loop)
5.2 템플릿 에디터 개선
- 문법 하이라이팅
- 자동완성
- 실시간 미리보기
Phase 6: 데이터베이스 및 백엔드 연동 (1일)
6.1 데이터베이스 스키마 업데이트
- relationships 테이블에 rest_api_settings 컬럼 추가
- 마이그레이션 스크립트 작성
6.2 백엔드 API 수정
- 관계 저장 시 REST API 설정 저장
- 관계 실행 시 REST API 호출 로직
🧪 테스트 계획
1. 단위 테스트
- RestApiSettings 컴포넌트 렌더링 테스트
- 입력값 검증 로직 테스트
- 템플릿 변수 치환 테스트
2. 통합 테스트
- 연결타입 선택 → REST API 설정 플로우
- 설정 저장 → 불러오기 테스트
- API 호출 → 응답 처리 테스트
3. E2E 테스트
- 전체 관계 생성 → 실행 플로우
- 다양한 API 서비스와의 연동 테스트
- 오류 상황 처리 테스트
🔒 보안 고려사항
1. 인증 정보 보호
- API 키, 토큰 등 민감 정보 암호화 저장
- 프론트엔드에서 민감 정보 마스킹 표시
- 로그에 민감 정보 노출 방지
2. API 호출 제한
- 호출 빈도 제한 (Rate Limiting)
- 허용된 도메인만 호출 가능하도록 제한
- 타임아웃 설정으로 무한 대기 방지
3. 입력값 검증
- URL 형식 검증
- JSON 템플릿 문법 검증
- XSS, 인젝션 공격 방지
📊 성능 최적화
1. 프론트엔드 최적화
- 컴포넌트 지연 로딩 (Lazy Loading)
- 설정 변경 시 디바운싱 적용
- 메모이제이션으로 불필요한 리렌더링 방지
2. 백엔드 최적화
- API 호출 결과 캐싱
- 비동기 처리로 응답 시간 단축
- 연결 풀링으로 리소스 효율화
🚀 배포 및 모니터링
1. 배포 전략
- 기능 플래그로 점진적 배포
- A/B 테스트로 사용성 검증
- 롤백 계획 수립
2. 모니터링
- API 호출 성공/실패율 모니터링
- 응답 시간 추적
- 오류 로그 수집 및 알림
📝 문서화
1. 사용자 가이드
- REST API 설정 방법 가이드
- 템플릿 변수 사용법
- 일반적인 API 연동 예제
2. 개발자 문서
- 컴포넌트 API 문서
- 백엔드 API 명세
- 확장 가이드
🎯 성공 지표
1. 기능적 지표
- REST API 설정 완료율 > 95%
- API 호출 성공률 > 98%
- 설정 저장/불러오기 성공률 > 99%
2. 사용성 지표
- 설정 완료 시간 < 5분
- 사용자 만족도 > 4.0/5.0
- 지원 요청 감소율 > 30%
📅 일정 계획
| 단계 | 기간 | 주요 작업 |
|---|---|---|
| Phase 1 | 1-2일 | RestApiSettings 컴포넌트 기본 구현 |
| Phase 2 | 1일 | 연결타입 선택 연동 |
| Phase 3 | 2-3일 | 인증 및 고급 기능 |
| Phase 4 | 1-2일 | 테스트 및 실행 기능 |
| Phase 5 | 2-3일 | 템플릿 시스템 고도화 |
| Phase 6 | 1일 | 데이터베이스 및 백엔드 연동 |
| 총 기간 | 8-12일 | 전체 기능 완성 |
🔄 향후 확장 계획
1. 추가 프로토콜 지원
- GraphQL API 지원
- WebSocket 연결
- gRPC 호출
2. 고급 기능
- API 응답 기반 조건부 실행
- 여러 API 순차/병렬 호출
- API 응답 데이터 파싱 및 저장
3. 통합 기능
- 외부 API 문서 자동 가져오기
- Postman 컬렉션 임포트
- OpenAPI 스펙 지원
이 계획서를 바탕으로 단계별로 구현을 진행하면 안정적이고 사용자 친화적인 REST API 외부호출 기능을 완성할 수 있습니다.