0
0

More than 3 years have passed since last update.

SAMでローカル実行したLambdaからMongodbへのアクセスを試してみたメモ

Last updated at Posted at 2021-03-13

概要

前回はフォルダ階層を導入した。
今回はDocumentDBを使った操作を確認できるようにする。
なお、DocumentDBはローカル版が用意されていないのでMongoDBを利用する。
MongoDB/DocumentDBには破壊的変更のある3系と4系があるが、今回は最新版である4.0を導入する。

ソースコード

やること

  • mongodbの単体テスト
  • nongodbのローカルでの実行
    • mongodbはdockerで動かす

やらないこと

  • デプロイ

MongoDBの導入

  • laradockを参考に導入。
    • ファイルシステムがwindowsと相性悪いのでvolumesを修正(ubuntuのdockerでは修正しなくても動いた)
docker/docker-compose.yml
version: '3.5'

networks:
  backend:
    driver: ${NETWORKS_DRIVER}

volumes:
  mongodb-data: {}

services:
### MongoDB ##############################################
    mongo:
      build: ./mongo
      ports:
        - "${MONGODB_PORT}:27017"
      volumes:
        - mongodb-data:/data/db
      networks:
        - backend

接続の確認には、robo3tを使用した。
公式- robo3tで接続する
Robo 3Tを使ってmonogoDBを確認する

MongoDBの利用

ハンドラ

src/lambda/handlers/users/post-user.ts
import { APIGatewayProxyHandler } from 'aws-lambda';
import * as response from '@/lambda/utilities/reponse';
import * as users from '../../users/persistant/users';

export const lambdaHandler: APIGatewayProxyHandler = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  const { body } = event;
  if (!body) {
    return response.badRequest('body is required')
  }
  try {
    const user = await users.create(JSON.parse(body))
    return response.ok(user);
  } catch (e) {
    console.error(e)
    throw e
  }
};

スタック

  • 環境変数を設定
    • mongodb-client-encryptionはbundleするときに入れろという内容のエラーが出たので、言われるままに追加。
cd/lib/sample-stack.ts
    const environment = {
      DOCUMENTDB_CONNECTION_STRING: '',
      DEFAULT_DB_NAME: ''
    }
    const bundling = {
      externalModules: ['aws-sdk', 'mongodb', 'mongodb-client-encryption'],
    }
    const mongoFunctionOptions = { environment, bundling, layers: [nodeModulesLayer] }

    const postUserFunction = new NodejsFunction(this, 'postUser', {
      runtime: lambda.Runtime.NODEJS_14_X,
      entry: `${entryHandlerDir}/users/post-user.ts`,
      functionName: 'post-user',
      handler: 'lambdaHandler',
      ...mongoFunctionOptions,
    });

実行用の設定

  • 関数名の下に環境変数を設定
    • 接続文字列は、localhosthost.docker.internalに置き換えている。参照
      • samはコンテナ上で動いているため、ホストのlocalhostのmongodbを見に行く必要がある
cdk/env.json
{
  "postUser7BA52173": {
    "DOCUMENTDB_CONNECTION_STRING": "mongodb://host.docker.internal:27017",
    "DEFAULT_DB_NAME": "sample"
  }
}
  • -n (-env-vars)オプションで環境変数設定ファイルを使用するように設定
cdk/package.json
    "bundle": "cdk synth > cdk.out/template.yaml",
    "localinvoke": "cd cdk.out && sam.cmd local invoke testAF53AC38 --no-event",
+    "dev-serve": "cd cdk.out && sam.cmd local start-api -n ../env.json"
  },

MongoDBのテスト

もともとJestを使っていたため、@shelf/jest-mongodbを使用。
インメモリでテストをするためには、mongodb-memory-serverを追加でインストールする。
インストール時のデフォルトのmongoのバージョンが4.0.14なのに注意

jest-mongodb-config.js
module.exports = {
  mongodbMemoryServerOptions: {
    binary: {
      version: '4.0.14',
      skipMD5: true
    },
    instance: {
      dbName: 'jest'
    },
    autoStart: false,
    instance: {}
  }
};

実践

POST http://localhost:3000/users HTTP/1.1

{
    "username": "user2",
    "age": 22
}

image.png

注意点

  • dockerでmongodbはwindowsとちょっと相性悪いぽい。
    • ファイルシステムの問題

疑問

npm info mongodb versionsnpm info @types/mongodbを試してみた。
mongodbの3系は3.6.4が最新であり、@types/mongodbは3.6.9が最新であった。
同期してない?
なお、'4.0.0-beta.1'には型定義ファイル同梱であった。

参考

jest mongodb
github shelfio/jest-mongodb
mongodb-memory-servere
Node.jsからMongoDBに接続してみる
github-mongo
Express + MongoDBで作成したAPIサーバーをJestでテストする
AWS DocumentDB
AWS DynamoDB/DocumentDBをローカルで確認する手順(自分用メモ)
Do You Need Mongoose When Developing Node.js and MongoDB Applications?
ts-jest
MongoDB, Mongo Express起動用docker-compose設定手順
@aws-cdk/aws-apigateway module
'mongodb-client-encryption'
stack over flow
linuxでhost.docker.internalを使う
Dockerコンテナ内からホストへlocalhost でアクセスしてみる
MongoDBを扱うExpressアプリをAWS Lambdaに乗せてサーバーレスにするgit lo
AWS SAMの環境変数設定方法
aws-cdk-examples
robo3t
公式- robo3tで接続する
Robo 3Tを使ってmonogoDBを確認する

0
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
0
0