Which type do I return with AWS lambda responses in typescript to suite AWS APIGateway Method Response?

Viewed 16791

I want to build a proper typescript project on AWS lambda.

Right now, I am having the following definitions:

export type HttpResponse = {
  statusCode: number;
  headers: {};
  body: string;
}

export async function readCollection (event, context, callback): Promise<HttpResponse>{

  console.log(event); // Contains incoming request data (e.g., query params, headers and more)

  const data =  [
    {
      id: "a7b5bf50-0b5b-11e9-bc65-6bfc39f23288",
      name: "some thing",
      uri: `/notifications/a7b5bf50-0b5b-11e9-bc65-6bfc39f23288`
    }
  ]

  const response = {
    statusCode: 200,
    headers: {
    },
    body: JSON.stringify({
      status: "ok",
      data: data
     })
  };

  return response;
};

But

Instead of my custom HttpResponse type, I want to use an official definition.

But which official type do I import and return?

4 Answers

The @types/aws-lambda package provides types for using TypeScript inside of an AWS Lambda function. For AWS Lambda functions invoked using API Gateway's Lambda Proxy integration type take the following steps:

Install the package

$ yarn add --dev @types/aws-lambda

Or if you prefer npm:

$ npm i --save-dev @types/aws-lambda

Then in your handler file:

import { APIGatewayProxyEvent, Context, APIGatewayProxyResult } from "aws-lambda"

export async function hello (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello world',
      input: event,
    })
  }
}

After days of research I found the answer so close ;)

you return Promise<APIGateway.MethodResponse>

import { APIGateway } from "aws-sdk";

export async function readCollection (event, context, callback): Promise<APIGateway.MethodResponse> {

  console.log(event); // Contains incoming request data (e.g., query params, headers and more)

  const data =  [
    {
      id: "a7b5bf50-0b5b-11e9-bc65-6bfc39f23288",
      name: "some thing",
      uri: `/notifications/a7b5bf50-0b5b-11e9-bc65-6bfc39f23288`
    }
  ]

  const response = {
    statusCode: "200",
    headers: {
    },
    body: JSON.stringify({
      status: "ok",
      data: data
     })
  };

  return response;
};

The AWS Lambda types define the handler as:

export type Handler<TEvent = any, TResult = any> = (
    event: TEvent,
    context: Context,
    callback: Callback<TResult>,
) => void | Promise<TResult>;

So essentially you get to decide what the return type is, thanks to the Generics.

If you're using other AWS services with the lambda (e.g. API Gateway), you're input and response may be different.


Link to the Handler type: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/index.d.ts#L1076-L1089

You need to return a callback otherwise if your lambda was triggered by an s3 put it will think it did not execute and will continue executing your function from time to time generating duplicated calls. You also need to return a callback from an API Gateway request so you can send a proper response to the user.

For success calls:

callback(null, response);

For error calls:

callback(error, null);
Related