Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

difference between res.send or res.json

What is the difference between

res.status(STATUS_CODE).send({"message" : "this is the message" });

and

res.status(STATUS_CODE).json({"message" : "this is the message" });

although checked the similar question but that is in context of express 3 and I am looking for express 4

like image 516
diEcho Avatar asked Jun 08 '16 09:06

diEcho


2 Answers

Ultimately, both will achieve the same thing. If you call res.send with an object, it will hit this switch in res.send:

switch (typeof chunk) {
// string defaulting to html
case 'string':
  if (!this.get('Content-Type')) {
    this.type('html');
  }
  break;
case 'boolean':
case 'number':
case 'object':
  if (chunk === null) {
    chunk = '';
  } else if (Buffer.isBuffer(chunk)) {
    if (!this.get('Content-Type')) {
      this.type('bin');
    }
  } else {
    return this.json(chunk);
  }
  break;
}

If the object you're sending it is not a Buffer - it will call res.json.

res.json simply sets the Content-Type header to application/json and runs the object through JSON.stringify - with specified replacer function and spacer value. Eventually it calls res.send.

This call of res.send is sent a string and the case statement will break resulting in the rest of the function being run. The remainder of the send function sets things like etag, content size etc. You can find out more by looking at the express code.

They start to differ when you send them non-object responses, such as strings, numbers etc. As in that case res.json will run it through JSON.stringify but res.send wont: resulting in different Content-Type headers and content.

edit: to answer your comment on the other answer, sending different status codes will still behave the same.

like image 56
MrWillihog Avatar answered Sep 21 '22 17:09

MrWillihog


.json calls .toJSON() method on the object (if it exists) and also sets the content-type header to application/json

But basically you can simulate .json with .send, if you do the above manually.


For example this middleware

(req, res, next) => {
    let x = {};
    x.toJSON = () => {
        console.log('oh yeah');
        return 15;
    };

    return res.json(x);
}

Prints

oh yeah

And returns 15 to the request with these headers (at least in my simple express app):

Connection →keep-alive
Content-Length →2
Content-Type →application/json; charset=utf-8
Date →Wed, 08 Jun 2016 10:16:09 GMT
ETag →W/"2-m/Mcf/Bik2qW08i9H48v8w"
Vary →Accept-Encoding
X-Powered-By →Express
like image 30
libik Avatar answered Sep 17 '22 17:09

libik