API 서버 설계와 구현에 대해 자세히 공유하려 합니다.
통합 API 서버는 다음 네 가지 주요 목표를 달성하기 위해 설계되었습니다:
API 서버의 역할을 단순화하고 DB 프로시저에서 더 많은 핵심 로직을 처리하도록 구조를 변경하여, 잦은 서버 배포 없이 DB 프로시저 수정만으로도 상당 부분의 로직 변경에 유연하게 대처할 수 있도록 구성했습니다.
export interface ProcedureResult {
/** 숫자 값: 0(정상), 양수(유효성 검사 결과), 음수(시스템 오류) */
numericData: number;
/** 문자열 값: 결과 메시지 */
textData: string;
/** 커서 값: 실제 데이터와 메타데이터 */
cursorData?: Array<{
data: Record<string, any>[];
fields: Record<string, any>[];
}>;
}
파편화된 시스템의 다양한 데이터베이스에 접근하기 위해 팩토리 메서드 패턴을 도입했습니다.
- connector/
├── baseConnector.ts // 추상 기본 클래스
├── postgresConnector.ts
├── mysqlConnector.ts
├── oracleConnector.ts
└── index.ts
- executor/
├── postgresExecutor.ts
├── mysqlExecutor.ts
├── oracleExecutor.ts
└── index.ts
export abstract class DBConnector {
static connectors: DBConnector[] = []; // 등록된 커넥터 관리
constructor() {
DBConnector.connectors.push(this); // 모든 인스턴스를 중앙에서 관리
}
abstract connect(): Promise<void>;
abstract query<T>(sql: string, params?: any[]): Promise<T>;
abstract disconnect(): Promise<void>;
abstract getClient(): Promise<any>;
// 종료 시 연결 해제 처리
static async cleanup(): Promise<void> {
for (const connector of DBConnector.connectors) {
try {
await connector.disconnect();
log(`${connector.constructor.name} disconnected successfully`);
} catch (err) {
error(`Error disconnecting ${connector.constructor.name}:`, err);
}
}
}
}
export const getConnector = (type: 'postgresql' | 'mysql' | 'oracle', connStr: string, options={}): DBConnector => {
if (type === 'postgresql') {
return PostgreSQLConnector.getInstance(connStr, options);
} else if (type === 'mysql') {
return MySQLConnector.getInstance(connStr, options);
} else if (type === 'oracle') {
return OracleConnector.getInstance(connStr, options);
} else {
throw new Error(`Unsupported database type: ${type}`);
}
};
여러 시스템에 분산된 사용자 계정을 중앙 집중식으로 통합했습니다.
체계적인 코드 구조로 유지보수 용이성을 확보했습니다.
const app: express.Express = express();
serverConfig(app);
/**
* 로깅 미들웨어 설정
*/
app.use(loggerMiddleware);
/**
* API 라우트 설정
*/
setupRoutes(app);
const port = Number(process.env.PORT);
app.listen(port, ipv4, () => {
log("server start port : ", port);
});
API 서버 설계를 통해 달성한 핵심 성과:
이러한 API 서버 설계는 전체 통합 시스템의 중추 역할을 담당하며, 향후 시스템 확장이나 변경에도 유연하게 대응할 수 있는 기반을 마련했습니다.