Skip to content

Feature request: first-class support for binary responses #4514

@dreamorosi

Description

@dreamorosi

Use case

As a customer, when I want to return binary responses, I need to: 1/ manually construct the API Gateway response object, 2/ base64 encode the body, 3/ set the isBase64Encoded: true, and 4/ set the appropriate headers.

import { readFile } from 'node:fs/promises';
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
import { compress } from '@aws-lambda-powertools/event-handler/experimental-rest/middleware';
import type { Context } from 'aws-lambda';

const app = new Router();

app.get('/logo', [compress()], async () => {
  const logoFile = await readFile(`${process.env.LAMBDA_TASK_ROOT}/logo.png`);
  return {
    body: logoFile.toString('base64'),
    isBase64Encoded: true,
    headers: {
      'Content-Type': 'image/png',
    },
    statusCode: 200,
  };
});

export const handler = async (event: unknown, context: Context) =>
  app.resolve(event, context);

This means I can't use the Web API Response object, nor get the same automatic encoding behavior I get when returning JSON objects.

Solution/User Experience

Customers should be able to return a Buffer or ArrayBufferLike or equivalent readable together with a content type header and Event Handler should base64 encode it (or skip this step if already a string) and set the isBase64Encoded: true field in the response:

import { readFile } from 'node:fs/promises';
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
import { compress } from '@aws-lambda-powertools/event-handler/experimental-rest/middleware';
import type { Context } from 'aws-lambda';

const app = new Router();

app.get('/logo', [compress()], async () => {
  const logoFile = await readFile(`${process.env.LAMBDA_TASK_ROOT}/logo.png`);
  return {
    body: logoFile, // Buffer<ArrayBufferLike>
    headers: {
      'Content-Type': 'image/png',
    }
  }
});

export const handler = async (event: unknown, context: Context) =>
  app.resolve(event, context);

Additionally, the current transformer function that converts Response objects to API Gateway responses currently doesn't take in account the actual encoding of the body as set in the headers and hardcodes isBase64Encoded to false unless compression is enabled.

Alternative solutions

Continue doing this manually and only with API Gateway response objects - which is not great.

Acknowledgment

Future readers

Please react with 👍 and your use case to help us understand customer demand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmedThe scope is clear, ready for implementationevent-handlerThis item relates to the Event Handler Utilityfeature-requestThis item refers to a feature request for an existing or new utility

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions