@asapjs/core
@asapjs/core는 ASAPJS 프레임워크의 진입점 패키지입니다. Application 클래스를 통해 Express.js 서버를 부트스트랩하고, 전역 설정 관리 함수와 로거를 제공합니다.
임포트
import { Application, getConfig, setConfig, hasConfig, logger } from '@asapjs/core';
getConfig,setConfig,hasConfig,logger는 내부적으로@asapjs/common에서 re-export됩니다.
이 페이지에서 찾을 수 있는 것
| 심볼 | 타입 | 설명 | 상세 |
|---|---|---|---|
Application | Class | Express 서버 부트스트랩 및 플러그인 관리 | 이 페이지 → |
AsapJSConfig | Interface | 애플리케이션 설정 타입 | 이 페이지 → |
getConfig() | Function | 전역 설정 객체 조회 | 이 페이지 → |
setConfig() | Function | 전역 설정 객체 설정 | 이 페이지 → |
hasConfig() | Function | 설정 초기화 여부 확인 | 이 페이지 → |
logger | Object | Winston 기반 로거 인스턴스 | 이 페이지 → |
참고: API 인덱스 페이지에 기재된
IConfig는AsapJSConfig의 구버전 이름입니다. 현재 코드에서 사용되는 정식 이름은AsapJSConfig(@asapjs/types)입니다.
Application
import { Application } from '@asapjs/core';ASAPJS는 Application 클래스를 통해 Express.js HTTP 서버를 부트스트랩합니다. __dirname과 설정 객체로 인스턴스를 생성한 후 run()을 호출하세요. extensions 배열에 선언된 플러그인(RouterPlugin, SequelizePlugin, SocketPlugin)을 순서대로 초기화하고 단일 호출로 서버를 시작합니다.
생성자
new Application(dirname: string, config: AsapJSConfig)| 파라미터 | 타입 | 설명 |
|---|---|---|
dirname | string | 컴파일된 출력 디렉터리의 절대 경로. 엔트리 파일에서 __dirname을 전달합니다. 서브모듈이 컨트롤러, 모델, 소켓 핸들러를 자동으로 탐색하는 데 사용됩니다. |
config | AsapJSConfig | 애플리케이션 설정 객체. 전역으로 저장되며 getConfig()를 통해 조회할 수 있습니다. |
run()
application.run(
initBeforeStartServer?: () => void | Promise<void>,
options?: { disableListenServer: boolean }
): Promise<express.Application>모든 모듈을 순서대로 초기화한 후 HTTP 서버를 시작합니다. Express 애플리케이션 인스턴스를 반환합니다.
| 파라미터 | 타입 | 설명 |
|---|---|---|
initBeforeStartServer | () => void | 모듈이 초기화된 후, server.listen() 이전에 호출되는 선택적 콜백. 데이터베이스 마이그레이션, 시드 데이터 삽입, 기타 시작 로직을 실행하는 데 사용합니다. |
options.disableListenServer | boolean | true이면 HTTP 서버가 생성되지만 listen()은 호출되지 않습니다. 서버 라이프사이클을 직접 제어하는 테스트 환경에 유용합니다. |
run() 내부 초기화 순서:
RouterPlugin.init()—extensions에'@asapjs/router'가 있는 경우: Express 앱을 생성하고, 전역 미들웨어(CORS, bodyParser)를 적용하며,dirname/route.ts에서 컨트롤러를 로드하고, Swagger UI를 설정합니다.SequelizePlugin.init()—extensions에'@asapjs/sequelize'가 있는 경우: 데이터베이스에 연결하고, 모델과 DTO를 등록합니다.- Sentry 초기화 —
config.sentry가 설정된 경우. http.createServer(app)— HTTP 서버를 생성합니다.SocketPlugin.init()—extensions에'@asapjs/socket'이 있는 경우: HTTP 서버에 Socket.IO를 초기화합니다.initBeforeStartServer()콜백 — 사용자 정의 시작 로직.server.listen(config.port)—disableListenServer가 설정되지 않은 경우.
getApp()
application.getApp(): express.Application내부 Express 애플리케이션 인스턴스를 동기적으로 반환합니다. run() 호출 전에는 undefined입니다.
getServer()
application.getServer(): http.Serverrun() 중에 생성된 http.Server 인스턴스를 동기적으로 반환합니다. run() 호출 전에는 undefined입니다.
destroy()
await application.destroy(): Promise<void>등록된 플러그인을 역순으로 정리하고 HTTP 서버를 종료합니다. 테스트 환경에서 서버를 정상적으로 종료하거나 graceful shutdown을 구현할 때 사용합니다.
process.on('SIGTERM', async () => {
await app.destroy();
process.exit(0);
});전체 예제
// src/index.ts
import { Application } from '@asapjs/core';
require('dotenv').config({ path: `${__dirname}/../.env` });
const debug = process.env.NODE_ENV === 'development';
const port = parseInt(process.env.PORT || '3000', 10);
new Application(__dirname, {
name: 'ASAPJS Example',
port,
basePath: 'api',
extensions: ['@asapjs/router', '@asapjs/sequelize'],
auth: {
jwt_access_token_secret: process.env.JWT_SECRET || 'change-me-in-production',
},
swagger: {
name: 'ASAPJS Example API',
version: '1.0.0',
description: 'Reference implementation for the ASAPJS framework.',
scheme: (debug ? 'http' : 'https') as 'http' | 'https',
host: debug ? `localhost:${port}` : 'api.example.com',
},
database: {
database: process.env.DB_NAME || 'asapjs_example',
username: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT || '3306', 10),
dialect: 'mysql',
logging: debug ? (query: string) => console.debug(query) : false,
},
}).run();중요:
extensions배열에'@asapjs/router'를 반드시 포함해야 합니다. 누락하면 라우팅, Swagger UI, 전역 미들웨어가 활성화되지 않습니다.
AsapJSConfig 인터페이스
new Application()의 두 번째 인수로 전달하는 전체 설정 객체입니다. @asapjs/types에서 정의됩니다.
import { AsapJSConfig } from '@asapjs/types';
interface AsapJSConfig {
port: number;
dirname: string;
extensions: string[];
basePath?: string;
name?: string;
middleware?: any[];
auth?: {
jwt_secret?: string;
jwt_access_token_secret?: string;
};
sentry?: {
dsn: string;
environment?: string;
};
swagger?: {
title?: string;
name?: string;
version?: string;
description?: string;
path?: string;
scheme?: 'http' | 'https';
host?: string;
auth_url?: string;
useAuth?: boolean;
userObject?: { [username: string]: string };
};
database?: {
host: string;
port: number;
username: string;
password: string;
database: string;
dialect: 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql';
logging?: boolean | ((sql: string) => void);
};
[key: string]: any;
}최상위 필드
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
port | number | 필수 | HTTP 서버가 수신 대기할 TCP 포트. |
dirname | string | 자동 | 컴파일된 출력 디렉터리의 절대 경로. Application 생성자가 첫 번째 인수에서 자동으로 설정합니다. |
extensions | string[] | 필수 | 활성화할 ASAPJS 플러그인 목록. '@asapjs/router'는 라우팅을 사용하려면 반드시 포함해야 합니다. 지원 값: '@asapjs/router', '@asapjs/sequelize', '@asapjs/socket'. |
basePath | string | 선택 | 모든 API 라우트의 URL 접두사 (예: 'api'로 설정하면 라우트가 /api/...에서 사용 가능). 기본값은 ''. |
name | string | 선택 | 사람이 읽을 수 있는 애플리케이션 이름. Swagger UI와 로그 출력에 표시됩니다. |
middleware | any[] | 선택 | 전역 Express 미들웨어 배열. CORS, bodyParser 이후에 적용됩니다. |
auth | object | 선택 | JWT 인증 설정. 어떤 라우트에서든 auth: true를 사용하는 경우 필요합니다. |
sentry | object | 선택 | Sentry 에러 추적 설정. |
swagger | object | 선택 | Swagger UI 설정. |
database | object | 선택 | Sequelize 데이터베이스 설정. extensions에 '@asapjs/sequelize'가 있을 때 필요합니다. |
[key: string] | any | 선택 | 임의의 애플리케이션별 데이터. getConfig()를 통해 조회할 수 있습니다. |
auth 필드
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
auth.jwt_access_token_secret | string | 필수 | jwtVerification 미들웨어가 JWT 토큰을 검증하는 데 사용하는 시크릿 키. 프로덕션 환경에서는 반드시 환경 변수로 주입하세요. |
auth.jwt_secret | string | 선택 | 레거시 호환용 시크릿 키. 새 프로젝트에서는 jwt_access_token_secret을 사용하세요. |
sentry 필드
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
sentry.dsn | string | 필수 | Sentry DSN(Data Source Name). |
sentry.environment | string | 선택 | Sentry 환경 식별자 (예: 'production'). 기본값은 'development'. |
swagger 필드
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
swagger.name | string | 선택 | Swagger UI 상단에 표시되는 제목. |
swagger.version | string | 선택 | Swagger UI에 표시되는 API 버전 문자열 (예: '1.0.0'). |
swagger.description | string | 선택 | Swagger UI에 표시되는 설명 문단. |
swagger.scheme | 'http' | 'https' | 선택 | Swagger “Try it out” 요청에 사용되는 URL 스킴. |
swagger.host | string | 선택 | Swagger “Try it out” 요청에 사용되는 호스트명 (예: 'localhost:3000'). |
swagger.auth_url | string | 선택 | Swagger OAuth2 플로우를 사용하는 경우의 OAuth2 인증 URL. |
swagger.useAuth | boolean | 선택 | true이면 Swagger UI에 Basic 인증을 적용합니다. userObject와 함께 사용합니다. |
swagger.userObject | { [username: string]: string } | 선택 | Swagger UI 접근 제어를 위한 Basic 인증 자격증명 맵. useAuth: true일 때 필요합니다. |
database 필드
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
database.database | string | 필수 | 연결할 데이터베이스 이름. |
database.username | string | 필수 | 데이터베이스 사용자. |
database.password | string | 필수 | 데이터베이스 비밀번호. |
database.host | string | 필수 | 데이터베이스 호스트 주소. |
database.port | number | 필수 | 데이터베이스 포트 (예: MySQL은 3306, PostgreSQL은 5432). |
database.dialect | string | 필수 | Sequelize 다이얼렉트 식별자: 'mysql', 'postgres', 'sqlite', 'mariadb', 'mssql'. |
database.logging | boolean | ((sql: string) => void) | 선택 | SQL 쿼리 로깅. false로 비활성화하거나 커스텀 함수를 전달합니다. |
getConfig()
import { getConfig } from '@asapjs/core';
const config = getConfig(); // AsapJSConfig 반환Application 생성자가 설정한 전역 설정 객체를 반환합니다. Application이 인스턴스화되기 전에 호출하면 Error('Config not initialized. Call setConfig() first.')를 던집니다. 함수 파라미터를 통해 설정 객체를 전달하지 않고도 애플리케이션 어디서나 설정 값에 접근할 수 있습니다.
import { getConfig } from '@asapjs/core';
// 서비스나 미들웨어 내에서 설정 값에 접근
const config = getConfig();
const jwtSecret = config.auth?.jwt_access_token_secret;
const dbHost = config.database?.host;setConfig()
import { setConfig } from '@asapjs/core';
const setConfig: (newConfig: AsapJSConfig) => void전역 설정 객체를 설정합니다. 일반적으로 Application 생성자가 내부적으로 호출하므로 직접 호출할 필요는 거의 없습니다. 테스트 환경에서 설정을 모킹하거나 Application 없이 개별 모듈을 초기화할 때 사용합니다.
| 파라미터 | 타입 | 설명 |
|---|---|---|
newConfig | AsapJSConfig | 설정할 설정 객체 |
import { setConfig } from '@asapjs/core';
// 테스트에서 설정 모킹
setConfig({
port: 0,
dirname: __dirname,
extensions: [],
});hasConfig()
import { hasConfig } from '@asapjs/core';
const hasConfig: () => boolean설정이 초기화되었는지 확인합니다. setConfig()가 호출된 적이 있으면 true, 없으면 false를 반환합니다. getConfig() 호출 전에 안전하게 설정 존재 여부를 확인할 때 사용합니다.
import { hasConfig, getConfig } from '@asapjs/core';
if (hasConfig()) {
const config = getConfig();
// ...
} else {
console.warn('설정이 아직 초기화되지 않았습니다');
}미문서화 갭:
setConfig()과hasConfig()는 현재 부트스트랩 페이지에 상세 문서가 없습니다. 위의 설명이 현재 가용한 전체 레퍼런스입니다.
logger
ASAPJS는 Winston 기반의 로거를 제공합니다. @asapjs/core의 logger export는 @asapjs/common 패키지의 Winston 인스턴스를 감싸는 래퍼입니다. 컬러라이즈된 사람이 읽기 쉬운 형식으로 stdout에 출력합니다.
import { logger } from '@asapjs/core';참고:
@asapjs/core는 내부적으로@asapjs/common에서logger를 재수출합니다 (packages/core/src/index.ts→export { logger } from '@asapjs/common').
Logger 인터페이스
interface Logger {
info: (message: string, ...args: any[]) => void;
error: (message: string | Error, ...args: any[]) => void;
warn: (message: string, ...args: any[]) => void;
debug: (message: string, ...args: any[]) => void;
}모든 메서드는 첫 번째 인자로 문자열 메시지를, 이후 가변 인자(...args)를 받습니다.
로그 메서드
debug
logger.debug(message: string, ...args: any[]): void가장 낮은 심각도. 상세한 내부 추적에 사용됩니다.
info
logger.info(message: string, ...args: any[]): void서버 시작 및 모듈 초기화와 같은 일반 정보 메시지입니다.
warn
logger.warn(message: string, ...args: any[]): void에러는 아니지만 문제나 성능 저하 상태를 나타낼 수 있는 조건입니다.
error
logger.error(message: string | Error, ...args: any[]): voiderror는 첫 번째 인자로 문자열 또는 Error 인스턴스를 받을 수 있습니다:
- 문자열: 메시지를 그대로 로깅합니다.
Error인스턴스:Error.message를 로그 메시지로 사용하고, 원본Error객체를 메타데이터에 포함합니다.
logger.error('사용자를 찾을 수 없습니다');
logger.error(new Error('DB connection failed'));
logger.error('쿼리 실패', err);출력 형식
모든 로그는 컬러라이즈된 사람이 읽기 쉬운 형식으로 콘솔에 출력됩니다:
2026-02-21 09:15:00 - info: [asapjs] 서버가 시작되었습니다
2026-02-21 09:15:03 - error: [asapjs] 데이터베이스 연결 실패형식: ${timestamp} - ${level}: [asapjs] ${message}
- 타임스탬프:
YYYY-MM-DD HH:mm:ss [asapjs]레이블이 모든 로그에 포함- 레벨별 색상 적용 (Winston
format.colorize())
로그 레벨
현재 공개 로거의 transport 레벨은 debug로 하드코딩되어 있습니다. 네 가지 레벨의 로그가 모두 출력됩니다.
심각도 순서(낮음에서 높음): debug < info < warn < error.
참고:
packages/core/src/util/logger.ts에ASAPJS_LOG_LEVEL환경 변수로 레벨을 제어하는 구조화된 로거가 구현되어 있으나, 현재@asapjs/core의 공개 API에 포함되지 않습니다.import { logger } from '@asapjs/core'는@asapjs/common의 로거를 반환하며, 이 로거에는ASAPJS_LOG_LEVEL이 적용되지 않습니다.
구조화된 로거 (미노출)
packages/core/src/util/logger.ts에는 프로덕션 환경에 적합한 구조화된 로거가 구현되어 있습니다. 이 로거는 현재 @asapjs/core의 공개 export에 포함되지 않습니다.
LoggerFacade 인터페이스
type LogFn = (message: string, meta?: LogMeta) => void;
interface LoggerFacade {
debug: LogFn;
info: LogFn;
warn: LogFn;
error: {
(message: string, meta?: LogMeta): void;
(message: string, err: unknown, meta?: LogMeta): void;
};
}LogMeta 인터페이스
export interface LogMeta {
operation?: string; // 호출 위치 (ClassName.methodName)
executeId?: string; // 요청/흐름 식별자
err?: unknown; // Error 객체
context?: Record<string, unknown>; // 도메인 데이터
[key: string]: unknown; // 추가 필드
}공개 로거와의 비교
| 항목 | 공개 로거 (@asapjs/common) | 미노출 로거 (core/util/logger.ts) |
|---|---|---|
| import | import { logger } from '@asapjs/core' | 공개 API 없음 |
| 출력 형식 | 컬러라이즈 텍스트 | JSON |
| 시그니처 | (message, ...args) | (message, meta?: LogMeta) |
| 레벨 제어 | 하드코딩 debug | ASAPJS_LOG_LEVEL 환경 변수 (기본: info) |
| meta 검증 | 없음 | 비객체 전달 시 warn + 호출 무시 |
| Error 정규화 | Error.message 추출 | { name, message, stack } 자동 정규화 |
사용 예제
import { logger } from '@asapjs/core';
// 서버 이벤트 로그
logger.info('User registered successfully');
// Error 인스턴스를 포함한 에러 로그
try {
const user = await UsersTable.findByPk(id);
} catch (err) {
logger.error('Database query failed', err);
throw err;
}
// 디버그 추적
logger.debug('Executing password hash');관련 항목
- @asapjs/router — RouterPlugin과 라우팅 설정
- @asapjs/sequelize — SequelizePlugin과 데이터베이스 설정
- @asapjs/socket — SocketPlugin과 Socket.IO 설정