pengz
pengz

Reputation: 2471

JavaScript NodeJS Joi validation for large numbers

I am creating an application in NodeJS 12 using the Joi validation library to validate the API request body.

I am having an issue with number data types that are more than 16 digits long.

I want to validate a number that is 18 digits long.

The validation works for smaller numbers but it does not work for larger numbers. I think this might be due to a limitation with the size of numbers.

I am not able to follow the selected answer in this similar question because the field cannot be converted to a string. It must be processed and stored as a number in the database.

Example value:

999830129121239112

Joi validation rule

ExampleNumber: Joi.number().integer().max(999999999999999999).allow(null),

Error message:

{"message":"'ExampleNumber' must be a safe number at body,ExampleNumber","field":"ExampleNumber"}

Upvotes: 7

Views: 10753

Answers (2)

GProst
GProst

Reputation: 10227

JS has Number.MAX_SAFE_INTEGER value which is equal to 9007199254740991. So if you're using numbers in JS which are bigger than this value then you'll most likely have a different result from what you expect. For example, 999830129121239112 in your example returns 999830129121239200 in JS, so if you try to save it to your DB it will be wrong.

Means if you're planning to use such big numbers in JS you have to use another type, i.e. String or BigInt (starting Node v10.4, also isn't supported by all browsers - check here)

But as I can see BigInt type support isn't yet implemented in Joi (judging by this closed issue: https://github.com/hapijs/joi/issues/1531) so I guess String is your option here.

It doesn't matter if you store the value as a string in JS, it will still be converted to a number when you save it to DB if the column is number type.

Upvotes: 8

Aritra Chakraborty
Aritra Chakraborty

Reputation: 12542

You need to use number.unsafe() to validate large numbers,

From the API doc:

const safeNumber = Joi.number();
safeNumber.validate(90071992547409924);
// error -> "value" must be a safe number

const unsafeNumber = Joi.number().unsafe();
unsafeNumber.validate(90071992547409924);
// error -> null
// value -> 90071992547409920

Upvotes: 8

Related Questions