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.