background
- The npm package
request-promise-native
used by the BFF Client requests the microservice interface to return ID precision lost
1713166949059674112 => 1713166949059674000
Why is it lost?
When storing binary, the maximum offset of the decimal point is 52 bits. The computer stores binary, and the binary that can be stored is 62 bits. If it exceeds, there will be rounding operations. Therefore, the largest integer that can be accurately represented in JS is Math.pow( 2, 53), decimal that is 9007199254740992 greater than 9007199254740992 may lose precision
- Reference: https://zhuanlan.zhihu.com/p/100353781
- When
request-promise-native
initiates a request, whenoptions.json
is notfalse
, it will useJSON.parse
to parse the body
if (self._json) {
try {
response.body = JSON.parse(response.body, self._jsonReviver)
} catch (e) {
debug('invalid JSON received', self.uri.href)
}
}
minimal demo
Build service API
1. Build Java Web Api:
- Reference: Building a RESTful Web Service
- Modify the service layer to make the minimum id value greater than the js precision limit
public long getId() {
return id + 1713166949059674112L;
}
* 修改 controller 层添加 post 请求
@PostMapping("/greeting_create")
public Greeting createGreeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
2. Request
- GET request:
curl http://localhost:8080/greeting
- POST request:
curl -X POST http://localhost:8080/greeting_create
{"id":1713166949059674120,"content":"Hello, World!"}
solution
1. Get the string of the response body, use JSONbig
to convert id
into a string
- Advantage: only affects the current request
Disadvantage: does not support POST request method,
- Passing parameters through json is not supported
- Passing parameters through form + json: false requires back-end interface support
- GET request
const rp = require('request-promise-native');
const jsonBigInt = require('json-bigint');
const getOptions = {
'method': 'GET',
json: false,
'url': 'http://localhost:8080/greeting',
};
const getRes = await rp(getOptions);
console.log('get result: ', jsonBigInt.parse(getRes));
- POST request: not supported, json is occupied, will definitely execute
JSON.parse
const rp = require('request-promise-native');
const jsonBigInt = require('json-bigint');
const postOptions = {
'method': 'POST',
'url': 'http://localhost:8080/greeting_create',
json: { name: 'test' },
};
const postRes = await rp(postOptions);
console.log('post result: ', jsonBigInt.parse(postRes));
2. Replace JSONbig.parse()
with JSON.parse()
- Advantages: Simple implementation, support for POST
- Disadvantage: affects all JSON.parse() parsing
const rp = require('request-promise-native');
const jsonBigInt = require('json-bigint');
async function jsonBigReplaceParse() {
const oldParse = JSON.parse;
JSON.parse = jsonBigInt.parse;
const postOptions = {
'method': 'POST',
'url': 'http://localhost:8080/greeting_create',
json: { name: 'test' },
};
const postRes = await rp(postOptions);
console.log('post result: ', postRes);
JSON.parse = oldParse;
}
~
~ This article is over, thanks for reading!
~
Learn interesting knowledge, meet interesting friends, and shape interesting souls!
Hello everyone, I'm Hermit King , the author of " Programming Samadhi ", my official account is " Programming Samadhi ", welcome to pay attention, I hope you will give more advice!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。