strongloop / loopback

LoopBack makes it easy to build modern applications that require complex integrations.
http://loopback.io
Other
13.23k stars 1.2k forks source link

Returning XML, CSV based on Accepts header or extension #970

Closed STRML closed 7 years ago

STRML commented 9 years ago

Is there any way to do this (say, inject a post-request, pre-response middleware)? Would really like to support GET /model(.json), GET /model.xml, and GET /model.csv, as well as GET /model with an Accepts header.

eugenehp commented 9 years ago

@STRML @superkhau

Campaign.afterRemote("**",function campaignAfterRemoteDonations(ctx,error,next){
        console.log('campaignAfterRemoteDonations',ctx.method.name);
        if( ctx.req.query.format != undefined )
            if( ctx.req.query.format.toLowerCase() == 'csv' ){
                ctx.res.setHeader("Content-Type", "text/csv");
                ctx.res.setHeader('Content-Type','application/force-download');
                ctx.res.setHeader('Content-Type','application/octet-stream');
                ctx.res.setHeader('Content-Type','application/download');
                ctx.res.setHeader('Content-Transfer-Encoding','binary');

                ctx.res.setHeader('Content-Disposition', 'attachment; filename=example.csv');

                ctx.res.end(ctx.result);
                console.log( ctx.result );
            }
        next( );
    });
pthieu commented 7 years ago

@STRML are you okay it the solution above? Been over the year since this issue was opened.

This might take a while for us to get to if you still require this. To speed up the process, you can do one of two things:

  1. If you still require this, open a new issue using the New issue button and fill in the template provided to you
  2. Open a PR adding this functionality yourself and we will review and merge. Will close this issue now as it's been over a year. Please use option #1 if you still require this.

I am closing; please re-open if solution above does not work for you.

STRML commented 7 years ago

Yeah, we did something similar in the end:

// Add CSV support.

// Yeah, really. Misspelled.
const resolveReponseOperation = HttpContext.prototype.resolveReponseOperation;
const csvReponse = { // trololol
  contentType: 'text/csv',
  sendBody: sendCSVBody
};
HttpContext.prototype.resolveReponseOperation = function(accepts) {
  if (accepts === 'text/csv' || accepts === 'csv') return csvReponse;
  return resolveReponseOperation.call(this, accepts);
};

function sendCSVBody(res: Response, data: Array<Object> | Object): void {
  if (!data.length || typeof data[0] !== 'object') {
    res.statusCode === 204;
  } else {
    res.send(json2csv({data}));
  }
}

This supports query strings like _format=csv as well.