3

I 've got a perl dancer app (providing a rest api) which works fine with JSON (de-)serialization. Now I'm need one additional special route, that provides a (dynamically created) csv file for download.

Here is the sample code:

#!/usr/bin/env perl
use Dancer2;
set serializer => 'JSON';

get '/normal' => sub {
    { 'I say ' => 'the json serializer works' };
};

get '/download' => sub {
    content_type 'text/csv';
    return  generateCsv();
};

sub generateCsv {
    return '
    1,2,3
    4,5,6
    ';
}

dance;

The response sent to the client has no body, only a http-header (with the correct content-type)

$> curl  -I  http://localhost:3000/download
HTTP/1.0 200 OK
Date: Fri, 23 Mar 2018 10:10:14 GMT
Server: Perl Dancer2 0.205002
Server: Perl Dancer2 0.205002
Content-Length: 0
Content-Type: text/csv

The dancer serializer is not happy with this:

Failed to serialize content: hash- or arrayref expected 
(not a simple scalar, use allow_nonref to allow this) 
at /usr/local/share/perl/5.22.1/Dancer2/Serializer/JSON.pm line 40. 
in /usr/local/share/perl/5.22.1/Dancer2/Core/Response.pm 

I can't find anything about the allow_nonref thing in the Dancer docs or in the source code.

Has anybody a hint for me?

dontPanic
  • 111
  • 8

2 Answers2

4

Use send_as:

get '/download' => sub {
    send_as Mutable => generateCsv();
};
choroba
  • 231,213
  • 25
  • 204
  • 289
3

I've found that send_file also works:

get '/download' => sub {
        send_file (\&generateCsv(), content_type => 'text/csv', filename => 'articleEbayStatus.csv');
};
dontPanic
  • 111
  • 8