일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- ojdbc6
- 인텔리제이
- 프로젝트 여러 개
- Stream
- maven
- 프로그래머스
- datagrip 한글깨짐
- DART
- @RequestBody
- Spring
- svn
- JavaScript
- javascript error
- flutter mac 설치
- 코어자바스크립트
- InteliJ
- Aspect
- tecoble
- Mac
- Java
- 봤어요처리
- node.js
- MySQL
- class-transformer
- db
- SQL
- eqauls-hashcode
- REST
- oracle
- TypeScript
- Today
- Total
개발자가 되고 싶은 개발자
JavaScript의 Number 표현범위 (Java의 int를 곁들인…) 본문
아래와 같이 일반적인 자료형의 범위를 넘어가는 요청을 방지하고자 하는 작업이 존재하였습니다.
처리하는 과정에서 JS의 기초적인 부분에 대해 망각하고 있어 정리합니다.
GET /items?page[offset]=0&page[limit]=200000000000000000000
쿼리스트링
잠시 쿼리스트링에 대해서 얘기해보겠습니다.
쿼리스트링은 데이터를 전달하는 기본적인 방법 중 하나입니다. URL의 일부이고, 이름에서 알 수 있듯이 문자열입니다.
HTTP 요청은 텍스트 기반이므로 쿼리스트링을 포함한 요청은 문자열로 데이터가 전송되게 됩니다.
요청 파라미터 검증
API 서버에서는 보통 미들웨어에서 파라미터에 대한 검증을 진행합니다.
Spring 프로젝트를 진행하는 동료분께 어떻게 방지하고 계신는지 여쭤보니 숫자형으로 변환하여 자료형의 범위를 벗어나는 것으로 에러를 반환하는 형태로 처리하신다고 들었습니다.
제가 담당중인 Node.js 환경의 미들웨어에도 분명 숫자형으로 변환하고 있었지만, 범위에 대한 에러는 발생하지 않았고 내부까지 도달하여 에러를 반환한 원인을 파악하고 있었습니다.
Java의 int
Java에는 표현 가능한 범위에 따라 int, double 등 여러 자료형들이 존재합니다.
int의 허용범위는 아래와 같습니다.
- 최소값: -2,147,483,648
- 최대값: 2,147,483,647
int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of 2^31-1.
일반적인 데이터의 경우 int 형으로 변환했을 것이고, 본문 서두에서 작성한 요청은 NumberFormatException이 발생할 것입니다.
String largeNumberStr = "200000000000000000000";
int convertedNumber = Integer.parseInt(largeNumberStr);
JavaScript의 number
JavaScript의 number 타입은 Java의 double과 같이 IEEE 754 표준을 따르는 64비트 부동소수점 형식을 사용합니다.
부동소수점 방식을 사용하기 때문에 정밀도가 떨어져 정확한 값을 표현할 수 없을 순 있어도 변환할 수 없는 값은 아니었기에 에러가 발생하지 않았고 그대로 내부 로직까지 도달할 수 있었습니다.
실제 발생했던 에러도 2.0E20… 와 같이 변환된 값이 에러 메시지에 노출되는 것을 확인할 수 있었습니다.
MAX_SAFE_INTEGER
조사하면서 Number. MAX_SAFE_INTEGER와 같은 정적 프로퍼티를 확인하였습니다.
추가로, Number.isSafeInteger() 메서드를 사용하여 안전한 정수 범위 내의 값인지 확인할 수 있습니다.
const limit = Number(req.query.page.limit);
if (!Number.isSafeInteger(limit) || limit > Number.MAX_SAFE_INTEGER) {
return res.status(400).json({ error: '유효하지 않은 limit 값입니다.' });
}
에러를 발생시키는 것도 아니고, 정확한 값도 아닐 수도 있다는 점은 금융거래 관련 작업에서 큰 문제를 야기할 수 있는 부분이기에 정리하였다.
정밀데이터를 다룰 때는 기본자료형 중 Bigint 혹은 Decimal과 같은 라이브러리의 도입을 검토할 필요가 있습니다.
새삼 점점 더 기본기의 중요성을 깨닫게 되는 요즘입니다.
'Dev > JavaScript & TypeScript' 카테고리의 다른 글
class-transformer란 무엇이고 왜 사용할까? (0) | 2024.08.15 |
---|---|
JavaScript의 기본 Error 객체 (0) | 2024.08.05 |
시퀄라이즈의 타입스크립트 호환성 (0) | 2024.07.03 |
인프런 강의 안봤는데 봤어요 스크립트 (3) | 2024.06.28 |
타입스크립트 심볼 타입 (Symbols) (0) | 2024.03.14 |