Node.js와 TypeScript로 구축된 MySQL/MariaDB용 보안 SQL 게이트웨이입니다. 이것은 연결 풀링 및 쿼리 실행 기능을 제공하는 Phase 1 구현입니다.
- HTTP REST API: HTTP 엔드포인트를 통한 SQL 쿼리 실행
- 연결 풀링: 효율적인 MySQL 연결 관리
- 쿼리 실행: SELECT, INSERT, UPDATE, DELETE 작업 지원
- 트랜잭션 지원: 트랜잭션으로 여러 쿼리 실행
- 헬스 모니터링: 헬스 체크 및 통계 엔드포인트
- 로깅: Winston을 사용한 포괄적인 로깅
- 입력 검증: Joi를 사용한 요청 검증
- TypeScript: 타입 안정성을 위한 완전한 TypeScript 지원
- Node.js 20+ (LTS)
- MySQL 또는 MariaDB 서버
- npm 또는 yarn
- 프로젝트 디렉토리로 이동:
cd studio-sql-gateway- 의존성 설치:
npm install- 환경 설정 파일 생성:
cp .env.example .env- 데이터베이스 자격 증명으로
.env파일 편집:
DB_HOST=localhost
DB_PORT=3306
DB_USER=your_user
DB_PASSWORD=your_password
DB_NAME=your_database자동 리로드로 개발 모드 실행:
npm run devTypeScript 빌드:
npm run build개발용 Watch 모드:
npm run watch빌드 및 시작:
npm run build
npm start단일 SELECT 쿼리 실행 (읽기 전용):
POST /api/query
Content-Type: application/json
{
"query": "SELECT * FROM users WHERE id = ?",
"params": [1],
"timeout": 5000
}응답:
{
"success": true,
"data": [...],
"fields": [...],
"rowCount": 1,
"executionTime": 45
}참고:
- 이 엔드포인트에서는 SELECT 쿼리만 허용됩니다
- INSERT, UPDATE, DELETE 쿼리는 거부됩니다
- 여러 SELECT 쿼리의 경우 이 엔드포인트를 여러 번 호출하세요 (읽기에는 트랜잭션이 필요 없음)
단일 명령 쿼리 실행 (INSERT/UPDATE/DELETE):
POST /api/command
Content-Type: application/json
{
"query": "INSERT INTO users (name, email) VALUES (?, ?)",
"params": ["John Doe", "john@example.com"],
"timeout": 5000
}응답:
{
"success": true,
"affectedRows": 1,
"insertId": 123,
"executionTime": 45
}참고:
- 이 엔드포인트에서는 INSERT, UPDATE, DELETE 쿼리만 허용됩니다
- SELECT 쿼리는 거부됩니다
- 단일 명령의 경우 이 엔드포인트를 사용하세요
- 원자성이 필요한 여러 명령의 경우
/api/transaction을 사용하세요
트랜잭션으로 여러 명령 쿼리 실행 (원자적 작업):
POST /api/transaction
Content-Type: application/json
{
"queries": [
{
"query": "INSERT INTO users (name, email) VALUES (?, ?)",
"params": ["John Doe", "john@example.com"]
},
{
"query": "UPDATE accounts SET balance = balance - ? WHERE user_id = ?",
"params": [100, 1]
}
]
}응답:
{
"success": true,
"results": [
{
"success": true,
"affectedRows": 1,
"insertId": 123,
"executionTime": 12
},
{
"success": true,
"affectedRows": 1,
"executionTime": 8
}
]
}참고:
- 모든 쿼리는 INSERT, UPDATE 또는 DELETE여야 합니다
- 하나의 쿼리라도 실패하면 모든 변경사항이 롤백됩니다
- 관련된 쓰기 작업에 대한 원자성을 보장합니다
서버 및 데이터베이스 상태 확인:
GET /api/health응답:
{
"status": "healthy",
"timestamp": "2025-12-16T10:30:00.000Z",
"database": {
"connected": true
},
"pool": {
"totalConnections": 10,
"freeConnections": 8,
"queueLength": 0
}
}연결 풀 통계 확인:
GET /api/stats응답:
{
"success": true,
"stats": {
"totalConnections": 10,
"freeConnections": 8,
"queueLength": 0
}
}| 변수 | 설명 | 기본값 |
|---|---|---|
SERVER_PORT |
서버 포트 | 3000 |
SERVER_HOST |
서버 호스트 | 0.0.0.0 |
DB_HOST |
MySQL 호스트 | localhost |
DB_PORT |
MySQL 포트 | 3306 |
DB_USER |
MySQL 사용자 | root |
DB_PASSWORD |
MySQL 비밀번호 | `` |
DB_NAME |
데이터베이스 이름 | test |
DB_CONNECTION_LIMIT |
풀의 최대 연결 수 | 10 |
DB_CONNECT_TIMEOUT |
연결 타임아웃 (ms) | 10000 |
LOG_LEVEL |
로깅 레벨 | info |
studio-sql-gateway/
├── src/
│ ├── config/
│ │ ├── database.ts # 데이터베이스 설정
│ │ └── logger.ts # Winston 로거 설정
│ ├── models/
│ │ └── types.ts # TypeScript 타입 정의
│ ├── services/
│ │ ├── connectionPool.ts # 연결 풀 관리
│ │ └── queryExecutor.ts # 쿼리 실행 서비스
│ ├── routes/
│ │ └── query.ts # API 라우트 핸들러
│ ├── utils/
│ │ └── sqlValidator.ts # SQL 쿼리 검증 유틸리티
│ └── index.ts # 애플리케이션 진입점
├── .env.example # 환경 변수 템플릿
├── .gitignore
├── package.json
├── tsconfig.json
└── README.md
모든 API 엔드포인트는 구조화된 에러 응답을 반환합니다:
{
"success": false,
"error": "에러 메시지",
"executionTime": 123
}일반적인 HTTP 상태 코드:
200: 성공400: 잘못된 요청 (검증 에러)500: 내부 서버 에러 (쿼리 실행 에러)503: 서비스 사용 불가 (데이터베이스 연결 에러)
이 구현은 기본적인 보안 기능을 포함합니다:
- 쿼리 타입 분리: Query API (SELECT만)와 Command API (INSERT/UPDATE/DELETE만)가 분리됨
- SQL 문장 검증: 각 엔드포인트는 허용된 문장 타입만 실행되도록 검증
- 위험한 키워드 필터링: 위험한 SQL 키워드 차단 (DROP, TRUNCATE, ALTER 등)
- 다중 문장 차단: 세미콜론으로 구분된 여러 SQL 문장 차단
- 문자열 리터럴 처리: 문자열/백틱 내부의 키워드는 안전하게 처리
- 파라미터화된 쿼리: 모든 쿼리는 기본적인 SQL 인젝션을 방지하기 위해 파라미터화된 실행 사용
프로덕션 사용을 위해서는 추가 보안 조치가 필요합니다:
- 인증 및 권한 부여
- Rate limiting
- TLS/SSL 암호화
- 감사 로깅
- 입력 살균 처리
- Phase 2: 보안 기능 (인증, Rate limiting)
- Phase 3: 모니터링 및 감사 로깅 (상세 로그, 통계, 관리자 대시보드)
ISC