I have this API endpoint, that is connected to this Lambda Function, written in Groovy, that consumes multipart/form-data
and returns a CSV or XLSX file.
I have the Lambda Function up and running, and it returns the CSV/XLSX file as base 64 string.
However, before putting in any more work on the app, I wish to be able to see that file be downloaded from Postman request.
A response whose body is base-64 encoding of the File to be returned.
like this:
Date: Tue, 17 Oct 2023 03:49:15 GMT
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Length: 31680
Connection: keep-alive
x-amzn-RequestId: 7aeba6af-b8e7-4e01-93b2-c7c01bf803ac
Content-Disposition: attachment; filename=Returned Postcards 0ct 4 2023.XLSX
x-amz-apigw-id: M7WXME3EiYcFyrw=
X-Amzn-Trace-Id: Root=1-652e042d-069a3c126955e0a648434148;Sampled=0;lineage=bad4f2c2:0
Note that, we defined our response header, in the code, to be:
Map<String, String> createResponseHeaders(String outputFileName) {
return [
('Content-Type') : this.getContentTypeHeader(outputFileName),
('Content-Disposition') : "attachment; filename=${outputFileName}".toString(),
]
}
private String getContentTypeHeader(String outputFileName) {
final String fileExtension = FileUtils.GetFileExtension(outputFileName).toLowerCase();
switch (fileExtension) {
case "xlsx":
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
case "csv":
return "text/csv";
}
throw new IllegalArgumentException("Content type for extension '${fileExtension}' not yet implemented");
}
Sure... It ends up being something like this...
return new APIGatewayProxyResponseEvent()
.withStatusCode(200)
.withHeaders(this.createResponseHeaders(outputFile.getName()))
.withIsBase64Encoded(true)
.withBody(Base64.getEncoder()
.encodeToString(outputFile.bytes))
When I send and download, I get a .txt file containing the raw base-64 output. I don't see the XLSX file I requested...
This:
Just the Postman-generated defaults:
Content-Type: multipart/form-data; boundary=<calculated when request is sent>
...
User-Agent: PostmanRuntime/7.33.0
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
How do I get this such that the response causes the file to actually download?!
I was able to fix the issue!
On the API Gateway page, for my endpoint, I do the following:
Accept
Content-Type
It should look like this in the console if you're trying this:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
(empty model)text/csv
(empty model)It should look like this on your console if you're trying this:
On the Postman side, I simply assign to Accept
header the desired Content-Type
(in this example, it is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
).
I made typo in my createResponseHeaders()
method. I fix it:
Map<String, String> createResponseHeaders(String outputFileName) {
return [
('Content-Type') : this.getContentTypeHeader(outputFileName),
('Content-Disposition') : "attachment; filename=\"${outputFileName}\"".toString(),
]
}
I then do that Send and Download... It worked!