DEV Community

loading...
Cover image for 'res.json()'s are different between a backend server and a frontend server

'res.json()'s are different between a backend server and a frontend server

jacobkim9881 profile image Jacobkim ・3 min read

While building web servers(Backend and frontend), I found information that responses between backend and frontend are different. As a backend server a response has information for backend server(Like server, socket, session, header and etc...) but as a frontend server a response has information for the frontend server(like header options, status, and etc...).

At a frontend server fetch loads json file like below:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))

//answer: Object { userId: 1, id: 1, title: "delectus aut autem", completed: false }
Enter fullscreen mode Exit fullscreen mode

Let me make a browser console response for fetch:

fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then(res => console.log(res))
Enter fullscreen mode Exit fullscreen mode

And console logged below:

Response
​
body: ReadableStream { locked: false }
​
bodyUsed: false
​
headers: Headers {  }
​
ok: true
​
redirected: false
​
status: 200
​
statusText: "OK"
​
type: "cors"
​
url: "https://jsonplaceholder.typicode.com/todos/1"
​
<prototype>: ResponsePrototype { clone: clone(), arrayBuffer: arrayBuffer(), blob: blob(), … }
Enter fullscreen mode Exit fullscreen mode

A response has such information on a browser.

On express.js server a response sends JSON like below:

let data = {data : 'example'}
app.get('/home', (req, res) => {
  res.json(data);
//{data : 'example'}
})

Enter fullscreen mode Exit fullscreen mode

Let me make the server console a response:

app.get('/home', (req, res) => {
  console.log(req);
  res.end();
})

Enter fullscreen mode Exit fullscreen mode

And I got long logs like below:

_readableState: ...
...
<ref *2> IncomingMessage {
  _readableState: ReadableState {
    objectMode: false,
    highWaterMark: 16384,
    buffer: BufferList { head: null, tail: null, length: 0 },
    length: 0,
    pipes: [],
    flowing: null,
    ended: false,
    endEmitted: false,
    reading: false,
    sync: true,
    needReadable: false,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: false,
    destroyed: false,
    errored: null,
    closed: false,
    closeEmitted: false,
    defaultEncoding: 'utf8',
    awaitDrainWriters: null,
    multiAwaitDrain: false,
    readingMore: true,
    decoder: null,
    encoding: null,
    [Symbol(kPaused)]: null
  },
  _events: [Object: null prototype] { end: [Function: clearRequestTimeout] },
  _eventsCount: 1,
  _maxListeners: undefined,
  socket: <ref *1> Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
...
Enter fullscreen mode Exit fullscreen mode

A response on a backend server has other messages now like a frontend server.

So res.json() looks same but has a different meaning between a backend server and a frontend server.

For example this fetch doesn't work on a frontend server:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then((response) => {response.json()})
  .then(json => console.log(json))
//undefined
Enter fullscreen mode Exit fullscreen mode

But this works:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))
Enter fullscreen mode Exit fullscreen mode

What's different as ES6 code? The first one doesn't return response.json() but the other does return because arrow function automatically returns without bracket. If like this:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then((response) => {return response.json()})
  .then(json => console.log(json))

//answer: Object { userId: 1, id: 1, title: "delectus aut autem", completed: false }
Enter fullscreen mode Exit fullscreen mode

then it will show the JSON.

But we use res.json() without return on express.js like below:

let data = {data : 'example'}
app.get('/home', (req, res) => {
  res.json(data); //without return
})
Enter fullscreen mode Exit fullscreen mode

So res.json() for a frontend server shouldn't be used as a backend server. For fullstack developers these should be aware as different meanings.

Discussion (0)

pic
Editor guide