Node.js API에서 BigInt 다루기 - MySQL BIGINT 변환 이슈

문제 상황

결제 시스템 API를 개발하던 중 이상한 버그를 발견했다. 주문 ID가 간헐적으로 다른 값으로 조회되는 현상이었다. 로그를 확인해보니 9007199254740992 이상의 큰 숫자에서만 문제가 발생했다.

원인은 JavaScript의 Number 타입 제약이었다. Number.MAX_SAFE_INTEGER2^53 - 1인데, MySQL의 BIGINT는 이보다 훨씬 큰 범위를 지원한다.

해결 방법

mysql2 드라이버는 이를 위한 옵션을 제공한다.

const mysql = require('mysql2');

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  database: 'payments',
  supportBigNumbers: true,
  bigNumberStrings: true
});

supportBigNumbers를 활성화하면 BIGINT 값을 안전하게 처리한다. bigNumberStrings: true로 설정하면 문자열로 반환되므로 정확도를 유지할 수 있다.

pool.query('SELECT order_id FROM orders WHERE id = ?', [1], (err, rows) => {
  console.log(typeof rows[0].order_id); // 'string'
  console.log(rows[0].order_id); // '9007199254740993'
});

추가 고려사항

문자열로 받은 후 클라이언트에 전달할 때도 문자열로 유지해야 한다. JSON.stringify는 문제없지만, 중간에 Number로 변환하는 순간 정확도를 잃는다.

API 스펙 문서에도 "ID는 문자열로 처리"라고 명시했다. 프론트엔드 팀에도 공유 완료.