simov / purest

REST API Client Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

display json body in browser

kvslee opened this issue · comments

I want to display json body in a browser. Console shows json data requested. But I cannot display the json data in a browser at the route, http://localhost:3000/api/items. Do I need any extra trick for this?

    customProvider.query()
        .get('items')  
        .qs({
            id: 10
        })
        .json({json: true})
        .auth(access_token)
        .request(function (err, res, body) {
            if ( !err && res.statusCode == 200) {
                      console.log( body );
                      return body;
               } else {
                 console.log( err );
               }
        });
commented

I'm not sure what exactly the problem is. You should probably paste the output data here.

Also the json method is used for sending JSON object to the server, the request's json:true option is set internally by Purest.

I may forget to wrap request with Express' app.get() and pipe. I find this sample in request forum.

app.get('/route', function(req, res, next) {
  request('http://domain.com')
    .on('response', function(response) {
       if (response.statusCode === 200)
          return;
       this.abort();
       next(new Error('there was something wrong with this request'));
    })
    .pipe(res)
  ;
});
commented

I'm still not getting how these two code snippets relate to each other.

@simov Thanks for checking this again. I may be confused about routing system. I could not display json body with this code previously:

var getItems = function() {
    customProvider.query()
        .get('items')  
        .qs({
            id: 10
        })
        .request(function (err, res, body) {
            if ( !err && res.statusCode == 200) {
                            console.log( body );
                            return body;
            } else {
                console.log( err );
            }
        });
};

I thought that I missed plugging the handler to my Express route (http://localhost:3000/api/items), when I found the code snippets that I posted yesterday as a sample. Then, I did read more Express route system and also found this at http://expressjs.com/starter/hello-world.html:

The req (request) and res (response) are the exact same objects that Node provides, 
so you can invoke req.pipe(), req.on('data', callback) and anything else you would do
without Express involved.

So, I just try this. Now I see successfully json body in a browser. So for now, I understand that request must be passed (piped) to Node http.ServerResponse instance to display json body in browser.

var getItems = function(req, res) {
    customProvider.query()
        .get('items') 
        .qs({
            id: 10
        })
        .auth(access_token)
        .request()
        .on('response', function(response) {
          if (response.statusCode !== 200)
            handleError(new Error('something went wrong\n'))
        })
        .pipe(res)
};

I still have one thing puzzled: I could display the same json body without the response 'on' event lines though. What is the real benefit to add the lines here?

var getItems = function(req, res) {
    customProvider.query()
        .get('items') 
        .qs({
            id: 10
        })
        .auth(access_token)
        .request()
        .pipe(res)
};

If you see that I misunderstand some pieces yet, please let me know. I am open to your guide. Thanks much.

commented

In route callbacks in Express does not work like a regular functions, you are either going to the next() callback or returning the result res.end(). That's why pipe(res) works, but return body does not.

Your other option is to

app.get('/route', function(req, res, next) {
  customProvider.query()
        .get('items')  
        .qs({
            id: 10
        })
        .request(function (err, _res, body) {
             res.setHeader('content-type', 'application/json')
             res.end(JSON.stringify(body))
        })
});

Note the inner _res to prevent shadowing the outer one.

@simov Thank you so much for clarification. Is there any performance difference when choosing either pipe(res) or res.end(). I am just curious if any of these is more preferred or standard.

I like your suggested option because I can handle error inside the request method. One more clarification: Purest docs says: "Purest sets json:true for all of your requests by default, so body is always a JSON object". This means that I can drop res.setHeader, right?

Thank again and you may close this issue anytime.

commented

Is there any performance difference when choosing either pipe(res) or res.end()

The first one is streaming it, the second one is loading it in memory and then sending it. For small JSON bodies it won't matter, this depends on your use case.

This means that I can drop res.setHeader, right?

Nope. With res.setHeader you are setting the response header, the request have its own header when not piped.