lamproxとlambda-utilities

AWS Lambdaのアプリケーション開発で利用している自作のフレームワークがそれなりにこなれてきたので、README.mdの日本語訳をのせて紹介します。

Lamprox

AWS Lambdaのlambda-proxy機能を使った開発のためのフレームワークです。

セットアップ

$ npm install lamprox

概念と使用方法

Lamproxは、AWS Lambdaのlambda-proxy機能のための最小限かつ柔軟なフレームワークです。
AWS Lambdaを使用して複数のエンドポイントを構築する場合の、認証、応答処理、およびエラー処理のための処理を、横断的に適用することができます。

Process

Lamproxはハンドラを複数のProcessで定義します。
Processは以下に示すような関数です。

interface Process<T, U, E> {
  (ambience: ProcessAmbience<T, E>): Promise<U>
}

interface ProcessAmbience<T, E> {
  /** Variables that pssed lambda function. */
  lambda: {
    event: APIGatewayEvent
    context: Context
    callback: ProxyCallback
  }
  /** Result that preceding process. */
  result: T
  /** Shared variables accross that processes. */
  environments: E
}

Processor

Processorは複数のプロセスを保持して順番に実行するクラスです。
Processorはbefore、main、after、response、onErrorの各プロセスを保持し、ハンドラとして実行します。

/** Preparing before main process. */
type BeforeProcess<T, E> = Process<void, T, E>
/** Main process for request. */
type MainProcess<T, U, E> = Process<T, U, E>
/** After process. */
type AfterProcess<U, E> = Process<U, U, E>
/** Process that creating proxy result. */
type ResponseProcess<U, E> = Process<U, ProxyResult, E>
/** Process that called when error occured. */
type OnErrorProcess<E> = Process<Error, ProxyResult, E>

interface IProcessor<T, U, E> {
  before: BeforeProcess<T, E>
  main: MainProcess<T, U, E>
  after: AfterProcess<U, E>
  response: ResponseProcess<U, E>
  onError: OnErrorProcess<E>

  toHandler: () => LambdaProxyHandler
}

関数群

一般に、Processorを直接生成する必要はありません。
Lamproxは、ハンドラを作成するためのいくつかの関数を提供します。

lamprox()

単純なラムダプロキシハンドラを作成します。
レスポンスボディを生成するメソッドを書くだけで、lambda-proxyのハンドラを作成できます。

lamprox: <U>(main: MainProcess<void, U, void>) => LambdaProxyHandler

buildHandler()

各種プロセス - befire、after、response、onError - とEnviromentsでラムダ関数を作成します。
Enviromentsはプロセス間で共有される値です。

namespace IProcessor {
  interface Params<T, U, E> {
    main: MainProcess<T, U, E>,
    environments: E,
    before?: BeforeProcess<T, E>
    after?: AfterProcess<U, E>
    response?: ResponseProcess<U, E>
    onError?: OnErrorProcess<E>
  }
}

buildHandler: <T, U, E>(params: IProcessor.Params<T, U, E>) => LambdaProxyHandler

prepareHandlerBuilder()

prepareHandlerBuilder()は、buildHandler関数を生成するための関数です。
多くのラムダ関数があると場合に、共通のプロセスを定義されたbuildHandler関数を生成することができます。

namespace PrepareHandlerBuilder {
  interface Params<T, U, E> {
    before?: BeforeProcess<T, E>
    after?: AfterProcess<U, E>
    response?: ResponseProcess<U, E>
    onError?: OnErrorProcess<E>
  }
}

interface BuildHandler<T, U, E> {
  (params: IProcessor.Params<T, U, E>): LambdaProxyHandler
}

prepareHandlerBuilder: <T, U, E>(preparedParams?: PrepareHandlerBuilder.Params<T, U, E>) => BuildHandler<T, U, E>

ユーティリティ

Lamproxにはnode-lambda-utilitiesが含まれていますが、lambda-proxyのためのいくつかのユーティリティ関数が用意されています。

generateDummyAPIGatewayEvent()

これは、ダミーのAPIGatewayEventを生成するための関数です。
node-lambda-utilitiesのinvokeHandler()と一緒に使用してハンドラをテストすることができます。

generateDummyAPIGatewayEvent: (params?: GenerateDummyAPIGatewayEvent.Params) => APIGatewayEvent

generateProcessAmbience()

Process関数実行時の引数となるProcessAmbienceを生成するための関数です。
これを使用すると、Processそれぞれをテストすることができます。

generateProcessAmbience: <T, E>(params: GenerateProcessAmbience.Params<T, E>) => ProcessAmbience<T, E>

lambda-utilities

AWS Lambdaのユーティリティ関数と型定義

インストール

$ npm isntall lambda-utilities

使用方法

型定義

lambda-utilities@types/aws-lambdaが提供するLambdaの基本な型定義を含みます。
以下のリストは、@types/aws-lambdaで提供されている型定義の一部です。

  • API Gatewayのイベントと応答
  • API Gateway CustomAuthorizerのイベントと応答
  • SNSイベント
  • S3作成時のイベント
  • Cognito User Poolイベント
  • CloudFormation Custom Resourceイベントとレスポンス
  • Context

lambda-utilities@types/aws-lambdaが提供していないDynamoDB Streamsイベントの型定義を提供します。
さらに、lambda-utilitiesは独自のイベントハンドラ用の汎用インタフェースを提供します。

interface Handler<Event, Callback> extends Function {
  (event: Event, context: Context, callback: Callback): void
}

ユーティリティ

Callback

SinonExpectationインタフェースを実装しているCallbackのモックを提供します。
引数callbackcallsFakeで実行されます。

generateMockCallback: (callback?: Callback) => MockCallback

Context

Contextのモックを提供します。
done、failとsucceedは、SinonExpectationインタフェースを実装しています。 パラメータとして関数を設定すると、その関数はcallsFakeで実行されます。

generateMockContext: (params?: GenerateMockContext.Params) => MockContext

export namespace GenerateMockContext {
  export interface Params {
    callbackWaitsForEmptyEventLoop?: boolean
    functionName?: string
    functionVersion?: string
    invokedFunctionArn?: string
    memoryLimitInMB?: number
    awsRequestId?: string
    logGroupName?: string
    logStreamName?: string,
    identity?: CognitoIdentity,

    getRemainingTimeInMillis?: () => number

    done?: (error: any, result: any) => void,
    fail?: (arg0: any) => void,
    succeed?: (arg0: any, arg1?: any) => void
  }
}

InvokeHandler

Lambdaのハンドラを実行する関数です。
モックと組み合わせてテストで使用できます。

const handler: Handler<TestEvet, TestCallback> = (event, context, callback) => {
  setTimeout(() => {
    callback(undefined, { foo: event.foo * 2 })
  }, 1000)
}

const callback = generateMockCallback((error, result) => {
  callback.once()
  assert.equal(result.foo, 42)
  assert.ok(callback.verify())
  done()
})

invokeHandler(handler, {
  event: { foo: 21 },
  callback: callback
})