express
express copied to clipboard
Allow specifying JSON stringifier
It would be great to be able to override the JSON.stringify
call in res.json()
, to use json-bigint
to serialize JSON objects
It looks like you opened a PR on this feature request before we could understand more. In order to ensure a conversation does not get fragmented, we will close this issue or the PR. Which one would you prefer us to keep open?
You can close the PR until discussion here has concluded. Alternatively, I can change the PR to draft mode?
As long as draft mode prevents others from accidentally commenting on the pr that is fine 👍
I saw your issue open when I was running errands (and still am), but was going to ask what this helps enable that the json replacer setting cannot do. I looked at the module you referenced but couldn't see it documented what the stringify actually did (but I am mobile, so could have missed it).
I know javascript has BigInt and JSON.stringify works with those no problems. Can you show what object you are trying to stringify that gives the wrong output?
Technically speaking, people can still comment on closed PRs. I turned the PR into draft mode and added a comment to discuss on the issue page until further notice.
I know javascript has BigInt and JSON.stringify works with those no problems.
This isn't true. Neither JSON.parse
nor JSON.stringify
have BigInt support, which is a major source of frustration for me right now :)
> 123948124923742397432n
123948124923742397432n
> JSON.parse('{"x":123948124923742397432}')
{ x: 123948124923742400000 }
> JSON.stringify(123948124923742397432n)
Uncaught TypeError: Do not know how to serialize a BigInt
at JSON.stringify (<anonymous>)
For now, we're using the json-bigint
library in order to have BigInt support when serializing/deserializing JSON. That library has two options: either use the native BigInt or use the bignumber.js
library. For other reasons that I won't go into, we're using the bignumber.js
implementation, whose default JSON representation is a string
> const BigNumber = require('bignumber.js')
> let x = new BigNumber('123948124923742397432')
> JSON.stringify({ x })
'{"x":"123948124923742397432"}'
In order to get it to serialize as a number, you have to use json-bigint
's function
> const JSONbig = require('json-bigint')
> JSONbig.stringify({ x })
'{"x":123948124923742397432}'
Ah, gotcha. So it would seem like using the json replacer option would work great for you use case. Is there something wrong with that setting that is keeping it from working for you?
I don't think that would work. The problem is if the replacer function converted a BigInt
/BigNumber
into a number, it would lose the precision and get rounded off. But if the replacer function returned the BigInt
/BigNumber
as a string (to keep the precision), it would serialize it as a string, not as a JSON number.
I don't think there's a way to use the replacer function to return a string and tell JSON.stringify
"hey trust me this is a JSON number, interpolate it directly without quotes".
@dougwilson Any update on this?
@dougwilson I think @brandon-leapyear makes a good case for why the json replacer function isn't adequate. I too think merging his PR would add powerful capabilities to Express. Any further thoughts?
yeah @dougwilson i also think that @brandon-leapyear PR will help express
@dougwilson I'm having to work around this issue as well, so agree that merging this PR would improve Express overall. Thanks @brandon-leapyear for taking the time with the fix.
Hey people. Any updates on this? @brandon-leapyear 's PR hasn't been merged yet
Hi -- wondering if there are any updates on this, as I'm struggling with the same at the moment.
@brandon-leapyear or others on the thread, would you mind sharing any current workarounds you have for this problem?
I believe the current workaround is to not use res.json, but manually run JSONbig.stringify. We have a custom middleware in NestJS that does this automatically.
On Sat, Apr 23, 2022, 4:29 AM juanfabrega @.***> wrote:
Hi -- wondering if there are any updates on this, as I'm struggling with the same at the moment.
@brandon-leapyear https://github.com/brandon-leapyear or others on the thread, would you mind sharing any current workarounds you have for this problem?
— Reply to this email directly, view it on GitHub https://github.com/expressjs/express/issues/4453#issuecomment-1107456201, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGUC75MGZEE6E4KGOIG3S5TVGPNKHANCNFSM4TIBOZRA . You are receiving this because you were mentioned.Message ID: @.***>
For anybody else looking at this issue, my temporary solution was to use the json-bigint
library and just override the JSON methods for my whole app. This may be too drastic for some but with the codebase I have, it does the job and I have no qualms about it since it is transparent otherwise.
I just put this code at the top of my app.ts
import JSONBig from 'json-bigint';
// DANGEROUSLY override JSON prototype methods to handle big ints.
JSON.parse = JSONBig.parse;
JSON.stringify = JSONBig.stringify;
I believe the current workaround is to not use res.json, but manually run JSONbig.stringify. We have a custom middleware in NestJS that does this automatically. … On Sat, Apr 23, 2022, 4:29 AM juanfabrega @.> wrote: Hi -- wondering if there are any updates on this, as I'm struggling with the same at the moment. @brandon-leapyear https://github.com/brandon-leapyear or others on the thread, would you mind sharing any current workarounds you have for this problem? — Reply to this email directly, view it on GitHub <#4453 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGUC75MGZEE6E4KGOIG3S5TVGPNKHANCNFSM4TIBOZRA . You are receiving this because you were mentioned.Message ID: @.>
Hey, I'm also figuring out a way to stringify BigInt using middleware. From the docs I understand one has to implement a middleware this way:
import { Request, Response, NextFunction } from 'express';
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
};
So I guess in your custom middleware, you must have modified the res
object and manually stringified the BigInt values? Or is it a little more complex to implement, if you can share a code snippet, it would be super helpful!