-
-
Notifications
You must be signed in to change notification settings - Fork 16.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional custom json replacer/spaces per response #2422
base: master
Are you sure you want to change the base?
Conversation
In some cases it is useful to be able to overwrite the json replacer at response level, in the end it is something related to the response. This change also makes it possible to simply say: `res.jsonReplacer = null; res.json(data);` to prevent the jsonReplacer from kicking in.
Please come up with a different API, as adding a magical property to Please also read through a previous request at #2098 and, if you can, provide a sample use-case for what the per-request replacer function you are trying to use. |
Here is a better idea: app.get('/', function() {
res.body = { '...': 'any json you want' } // use that instead of res.json()
res.jsonReplacer = function(){ /* whatever */ }
next()
})
app.use(function(req, res, next) {
if (!res.body) return next()
res.send(JSON.stringify(res.body, res.jsonReplacer))
}) Which doesn't require any changes to the core at all. |
I don't think we want to use res.send for json. |
Hi @rubenstolk , have you had time to come up with a different API yet? |
Not yet, but I will, hopefully have some time this weekend. Ruben Stolk CHANGER, Raising the bar in Online Experience! +91 95 6105 0034 INDIA OFFICE NETHERLANDS OFFICE On Fri, Oct 31, 2014 at 7:06 PM, Douglas Christopher Wilson <
|
If you really think it is a good idea to add it to express itself, the best api as of now would be this: res.set('json replacer', function(){})
res.json(data) Thus, allowing to override any I'd totally went for it in |
I don't like the idea of Mainly because set/get probably will not not exist in 5 and this is additional overhead. Can we do |
Otherwise |
em, pardon? Isn't json(num, data) being removed in 5.x? |
I was under the impression this PR was a feature request for 4, since that is where is PR is based. @rubenstolk what version are you requesting this feature in? |
@dougwilson I'm not sure it matters. I'm wondering where we can implement the most reasonable interface for the feature. |
@Fishrock123 I was just saying your suggestion is impossible to implemented in 3/4 is all, as it will break current (deprecated) uses of What is wrong with |
Plus I'm still waiting the hear what the use-case is for a per-request json replacer. The provided use-case from the last time this was requested was fundamentally flawed and made no sense, which contributed to why it wasn't added. |
Nothing actually. I forgot that this was actually stringifying it. >_< This is the most reasonable approach yeah. I don't think we should add it regardless of use case. |
Guys, I wasn't aware of the fact that we could use My use case:
|
You... can't. It was a suggestion for a possible implementation, but you'd have to fully implement |
lib/response.js
Outdated
@@ -223,7 +223,10 @@ res.json = function json(obj) { | |||
|
|||
// settings | |||
var app = this.app; | |||
var replacer = app.get('json replacer'); | |||
var replacer = res.get('json replacer'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
res.get
is an alias to res.getHeader
. This wouldn't be stored as a header value, besides the fact that Node.js will also ignore your request to res.set()
a function...
OK got it, I'll come up with something else then, give me more time. |
Because |
Using your code right now, the following app: var express = require('./index')
var app = express()
app.set('json replacer', function (key, value) {
if (key === 'id') return
return value
})
app.use(function (req, res) {
res.set('json replacer', function (key, value) {
if (key === 'secret') return
return value
})
res.json({
id: 3,
secret: 'keyboardcat',
name: 'loki'
})
})
app.listen(3000) Results in the following HTTP response:
Notice how the json replace I tried to set with |
Oh, sorry @rubenstolk I didn't realized you replied. You can just make a new comment rather than replying by completely replacing the content of an old comment, which is really confusing and doesn't let me know you made a reply. |
Oh, and FYI, to me the use-case for adding this I guess sounds valid, though using express to do your DTO -> DTO transformations seems a little heavy-handed to me. |
Well, I'm not using express per se for it, but express has a |
@dougwilson What do you think about the current approach? A separate 'createJSON' method which is used by both |
Interested to hear if this is going to work out or not. FYI, currently I'm living with this patch in my code: // TODO: this is a non desired override because it might not survive express updates
// Hopefully https://github.com/strongloop/express/pull/2422 works out
app.response.__proto__.json = function (obj) { // jshint ignore:line
var replacer = typeof this.jsonReplacer !== 'undefined' ?
this.jsonReplacer : this.app.get('json replacer');
var spaces = typeof this.jsonSpaces !== 'undefined' ?
this.jsonSpaces : this.app.get('json spaces');
var body = JSON.stringify(obj, replacer, spaces);
if (!this.get('Content-Type')) {
this.set('Content-Type', 'application/json');
}
return this.send(body);
}; |
So, it's still open because we need to address this (the issue about the replacer/spaces scope) in some way, but I'm not sure the current implementation in the PR would work out, i.m.o. |
While I don't have a use for setting
Basically, |
Likewise, I could see something like
|
+1. This would be very helpful when escaping output from certain requests, and not from others. |
5f268a4
to
9848645
Compare
eb10dba
to
340be0f
Compare
In some cases it is useful to be able to overwrite the json replacer at response level, in the end it is something related to the response.
This change also makes it possible to simply say:
res.jsonReplacer = null; res.json(data);
to prevent the jsonReplacer from kicking in.