LoginSignup
4
0

AWS SAMでLambdaを作成する

まずは、AWS SAM CLIを用いてテンプレート環境を作成します。事前に、AWS SAM CLIのインストールを公式ドキュメントに従って行なってください。
準備が完了したら、テンプレートを作成します。

sam init

質問には以下のように答えます。
スクリーンショット 2023-12-26 16.30.09.png
以下のようにアプリケーションが生成されたら準備完了です。
スクリーンショット 2023-12-26 16.30.36.png
template.yamlsamconfig.tomlはLambdaをデプロイするためのSAMの設定、hello-worldにはLambdaのコードが記述されています。eventsはテストに利用するLambdaのダミー入力です。

Prismaを導入する

次に、PrismaをLambdaに導入してローカル環境で利用可能にします。

npm install prisma --save-dev

パッケージを導入したら、Prismaプロジェクトを初期化します。

npx prisma init

prisma/schema.prisma.env.gitignorehello-worldに生成されます。
schema.prismaで利用するデータベースのテーブルのモデル化を行ってください。
そして、Lambdaからデータベースにアクセスするためのクライアントを準備します。

npm install @prisma/client

パッケージの導入と、Prismaクライアントやモデルの情報を扱うためのコードをnode_modulesに生成させます。

npx prisma generate

これで、Lambda内でPrismaを扱うための準備は完了です。

最後にPrismaをモックしてテストできるようにします。
モックしやすいように、アプリ全体でPrisma Clientをインスタンス化した1つのものを利用するようはシングルトンな構成に変更します。

client.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();
export default prisma;

データベースにアクセスするコードはこれを使うように書き換えてください。
そして、テスト環境が設定された後、Prisma Clientをモックするようにします。モックするために利用するライブラリを導入します。

npm install jest-mock-extended --save-dev

次に、モックを行うコードを記述します。

tests/singleton.test.ts
import { PrismaClient } from '@prisma/client'
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended'

import prisma from './client'

jest.mock('./client', () => ({
  __esModule: true,
  default: mockDeep<PrismaClient>(),
}))

beforeEach(() => {
  mockReset(prismaMock)
})

export const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient>

このファイルが呼ばれた後にPrisma Clientを呼び出すと代わりにprismaMockを呼び出すようになります。さらに、テストコードではprismaMockで各メソッドの戻り値の設定などを行えます。
Jestの設定でsetupFilesAfterEnvを設定することで、このファイルをテスト環境が設定された後に呼び出させます。

jest.config.ts
export default {
    transform: {
        '^.+\\.ts?$': 'ts-jest',
    },
    clearMocks: true,
    collectCoverage: true,
    coverageDirectory: 'coverage',
    coverageProvider: 'v8',
    testMatch: ['**/tests/unit/*.test.ts'],
    setupFilesAfterEnv: ['<rootDir>/singleton.ts'],
};

SAMの設定を変更する

最後にこれまでのコードをSAMからAWS Lambdaに上げ利用できるようにします。
まずは、prisma/schema.prismanode_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.nodeをAWSへアップロードするバンドルされたコードに含めるためコード内で呼び出すようにします。

client.ts
import { PrismaClient } from '@prisma/client';
import schema from '@/prisma/schema.prisma';
import x from '@/node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node';

if (process.env.NODE_ENV !== 'production') {
  console.debug(schema, x);
}
const prisma = new PrismaClient();
export default prisma;

schema.prismabinaryTargetsをそれに合わせて修正してください。

schema.prisma
generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "rhel-openssl-1.0.x"]
}

この変更は必ず呼び出されるところであればどこでも問題ないです。
最後にtemplate.yamlの設定を変更します。

HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Environment:
        Variables:
          DATABASE_URL: xxx
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
        - app.ts
        Loader:
          - .prisma=file
          - .so.node=file
        AssetNames: '[name]'

DATABASE_URLを渡すようにして、esbuildの設定の要素にLoaderAssetNamesを追加しました。
DATABASE_URLに渡すconnection_limitの値はこちらを参考して下さい。

これで準備完了です。sam buildしてsam deployすればPrismaを使ったLambdaを作成できます。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0