266

What is actual difference between res.send and res.json as both seems to perform same operation of responding to client.

hexacyanide
  • 88,222
  • 31
  • 159
  • 162
Dhanu Gurung
  • 8,480
  • 10
  • 47
  • 60
  • 92
    Take a moment to note how the folks posting answers just went to github and read the source code. This is a good habit to learn and establish. The Truth lies in The Source. – Peter Lyons Sep 27 '13 at 02:44
  • 39
    @PeterLyons I agree this is a good habit, but did you mean that ram should have looked at the source instead of asking the question? Doesn't this defeat the purpose of this site? The presence of this question, with answers referring to a good source (The Source!) is useful. – LinusR Feb 25 '14 at 17:15
  • 5
    Yes, teach a man to fish and all. – Peter Lyons Feb 28 '14 at 21:32
  • 86
    When we are told "RTFS" (Read The Source) it actually means that the docs fail to communicate what they should. Yes, having the source allows us to check it, but one should need not to get to it except in obscure cases. All these Express features are Really Great, but the docs fall short, by a lot. SO is full of questions about Express things that people can't understand from the docs (happens to me). – Juan Lanus Mar 30 '14 at 19:14
  • 4
    Sometimes reading source is not sufficient and as a good explanation may arise from answers, this will ensure the best understanding of the concept involved. Some people would simply read source and understand, but what about beginners who are not necessarily javascript friendly ? Think about it. – cram2208 Jul 31 '15 at 03:01
  • @PeterLyons but asking the question on here instead wins internet points ;) Question has 79 upvotes at time of writing. – Foo42 Jun 06 '16 at 07:48
  • 1
    I agree that docs are poor if they don't explain basics like these, and we should all stop badgering new engineers to "read the source" until they're ready to – codyc4321 Dec 02 '16 at 00:43
  • 1
    As a junior dev, I found @PeterLyons comment to be very useful. It's useful to note that there's another option when I'm confused- read the source code. I've seen people do this once or twice, but hadn't yet made it part of my debugging steps. Now I will. His comment doesn't negate the awesomeness of SO, but, rather, helps new coders realize there's another tool to put in our toolbelt :-) – danisyellis Aug 06 '17 at 02:09
  • @PeterLyons Your advice is not a new one. Most of us know that Truth lies in the source. that doesn't mean we should read source. What is the point of developing if we are reading source code, everytime something comes up. Writing code also means that to not reinvent the wheel. We should only read docs only if we have no options left. I am very curious like why are you here on stackoverflow? There are no source code given here. Please understand the purpose of stackoverflow. We are here because docs are not written properly. – Harsh Shah Jul 16 '23 at 20:11

4 Answers4

261

The methods are identical when an object or array is passed, but res.json() will also convert non-objects, such as null and undefined, which are not valid JSON.

The method also uses the json replacer and json spaces application settings, so you can format JSON with more options. Those options are set like so:

app.set('json spaces', 2);
app.set('json replacer', replacer);

And passed to a JSON.stringify() like so:

JSON.stringify(value, replacer, spacing);
// value: object to format
// replacer: rules for transforming properties encountered during stringifying
// spacing: the number of spaces for indentation

This is the code in the res.json() method that the res.send() method doesn't have:

var app = this.app;
var replacer = app.get('json replacer');
var spaces = app.get('json spaces');
var body = JSON.stringify(obj, replacer, spaces);

The method ends up as a res.send() in the end:

this.charset = this.charset || 'utf-8';
this.get('Content-Type') || this.set('Content-Type', 'application/json');

return this.send(body);
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
hexacyanide
  • 88,222
  • 31
  • 159
  • 162
92

See: res.json source code on expressjs.

res.json eventually calls res.send, but before that it:

  • respects the json spaces and json replacer app settings
  • ensures the response will have utf-8 charset and application/json Content-Type
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
24

Looking in the headers sent...

res.send uses content-type:text/html

res.json uses content-type:application/json

edit: send actually changes what is sent based on what it's given, so strings are sent as text/html, but if you pass it an object it emits application/json.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Roger Heathcote
  • 3,091
  • 1
  • 33
  • 39
2

res.json forces the argument to JSON. res.send will take an non-json object or non-json array and send another type. For example:

This will return a JSON number.

res.json(100)

This will return a status code and issue a warning to use sendStatus.

res.send(100)

If your argument is not a JSON object or array (null, undefined, boolean, string), and you want to ensure it is sent as JSON, use res.json.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
  • In this sentence: `will take an non-json object or array` -> we read it like: `non-json object` or `array`. so please make it more clear if possible. – yaya Sep 25 '20 at 21:41