头图

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

  • When request-promise-native initiates a request, when options.json is not false , it will use JSON.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:

    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!


编程三昧
54 声望10 粉丝

学习有趣的知识,交识有趣的朋友,造就有趣的灵魂!