Serverless NestJS
NestJSを利用したLambda&API GatewayのServerlessをやってみます。
注意点としては、NestJSはExpress.jsと比較すると重いフレームワーク(フルスタック)なので、起動に時間がかかってしまい、あまりサーバレスに向いているとは言えないです。
が、個人で利用する場合や社内系のアプリケーションの場合などは、サーバレスだと安くて試しやすいと思うので、是非使ってみてください。
NestJSプロジェクト作成
いつものやつです。
ひとまずローカルでHello Worldができる状態にします。
プロジェクト作成
$ nest new nest-serverless-test
動作確認
$ cd nest-serverless-test
$ npm run start
~ 中略 ~
[Nest] 3935 - 2020-02-29 19:19:07 [NestApplication] Nest application successfully started +1ms
$ curl localhost:3000
Hello World!
Serverlessの設定
ここからServerlessの設定を行っていきます。
パッケージインストール
$ npm install -g serverless
$ npm install i aws-serverless-express
$ npm install i aws-lambda
$ npm install i serverless-offline
$ npm install -D serverless-layers
Lambdaのhandler作成
Lambdaなので、いつサーバが切り替わるのかわからないことから、expressインスタンスをキャッシュして、起動済みであればキャッシュを利用し起動済みでない場合は新しく起動するという処理になっています。
import { Context, Handler } from 'aws-lambda';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Server } from 'http';
import { ExpressAdapter } from '@nestjs/platform-express';
import { createServer, proxy } from 'aws-serverless-express';
import * as express from 'express';
let cachedServer: Server;
async function bootstrapServer(): Promise<Server> {
const expressApp = express();
const adapter = new ExpressAdapter(expressApp);
const nestApp = await NestFactory.create(AppModule, adapter);
await nestApp.init();
return createServer(expressApp);
}
export const handler: Handler = async (event: any, context: Context) => {
if (!cachedServer) {
cachedServer = await bootstrapServer();
}
return proxy(cachedServer, event, context, 'PROMISE').promise;
};
Serverlessの設定ファイル作成
ルートディレクトリにserverless.yamlを作成して設定を行います。
service: nestjs-serverless-test
plugins:
- serverless-layers
- serverless-offline
custom:
defaultStage: dev
profiles:
dev: default
prod: prod
serverless-layers:
layersDeploymentBucket: nestjs-serverless-test-bucket
provider:
name: aws
runtime: nodejs12.x
region: ap-northeast-1
stage: ${opt.stage, 'dev'}
profile: ${self:custom.profiles.${self:provider.stage}}
environment:
SERVERLESS_STAGE: ${self:provider.stage}
package:
individually: true
include:
- dist/**
exclude:
- '**'
functions:
index:
handler: dist/handler.handler
events:
- http:
path: '/'
method: any
- http:
path: '{proxy+}'
method: any
ローカルテスト
serverless-offlineを利用することでローカルでもテスト可能になりますので、試しに実行してみます。
$ npm run build
$ sls offline
Serverless: Starting Offline: dev/ap-northeast-1.
Serverless: Routes for index:
Serverless: ANY /
Serverless: ANY /{proxy*}
Serverless: POST /{apiVersion}/functions/nestjs-serverless-test-dev-index/invocations
$ curl localhost:3000
Hello World!
これで動作確認ができました。
本番にデプロイしていきます。
デプロイ
S3のBucket作成
serverless-layersではs3バケットを利用するので、バケットを作成しておきます。
serverless.yamlのserverless-layers->layersDeploymentBucketで指定したバケット名を指定します。
$ aws s3 mb s3://nestjs-serverless-test-bucket
make_bucket: nestjs-serverless-test-bucket
AWSへのデプロイ
nestをbuildしてからdeployを行う必要があります。
$ nest build
$ sls deploy
~ 中略 ~
Serverless: Stack update finished...
Service Information
service: nestjs-serverless-test
stage: dev
region: ap-northeast-1
stack: nestjs-serverless-test-dev
resources: 12
api keys:
None
endpoints:
ANY - https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/
ANY - https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/{proxy+}
functions:
index: nestjs-serverless-test-dev-index
layers:
None
$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/
Hello World!
endpointsに記載されているURLにアクセスできれば無事デプロイ完了です。
ちなみに本番環境へのリリースはsls deploy --stage prod
です。
環境変数を渡す
この後はもう少し実践的な内容になります。
環境変数を設定してデプロイする方法です。
Serverlessの設定ファイル作成
今回は環境変数を設定ファイルに書き出しておいて、それを読み取りLambdaの環境変数に渡してあげるという方式でいきます。
service: nestjs-serverless-test
plugins:
~ 同じなので省略 ~
custom:
defaultStage: dev
profiles:
dev: default
prod: prod
# ここを追加する
otherfile:
environment:
dev: ${file(./conf/dev/env.yml)}
prod: ${file(./conf/prod/env.yml)}
serverless-layers:
layersDeploymentBucket: nestjs-serverless-test-bucket
provider:
name: aws
runtime: nodejs12.x
region: ap-northeast-1
stage: ${opt.stage, 'dev'}
profile: ${self:custom.profiles.${self:provider.stage}}
environment:
SERVERLESS_STAGE: ${self:provider.stage}
# ここを追加する
TEST_ID: ${self:custom.otherfile.environment.${self:provider.stage}.TEST_ID}
package:
~ 同じなので省略 ~
functions:
~ 同じなので省略 ~
追加したのは、custom配下にotherfile
を設定しました。
ここにprofileごとのファイルを指定しました。
また、provider->environmentに環境変数に追加したいものを指定して、otherfileに指定したファイルを読み取るように設定します。
環境変数の読み取り
パッケージインストール
$ npm i --save @nestjs/config
環境変数をNestアプリケーションに登録する
export default () => ({
test_id: process.env.TEST_ID
});
moduleでconfiguration読み込み
ConfigModule.forRootにloadプロパティを設定し、先ほど作成したconfiguration.tsファイルを読み込みます。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import configuration from './config/configuration';
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
環境変数を利用する
controllerのconstructorにConfigServiceを指定してDIさせます。
あとは、利用したいときにconfigServiceのgetメソッドを利用してconfiguration.tsファイルに設定したキーを指定して取得します。
これで環境変数が取得できます。
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { ConfigService } from '@nestjs/config';
@Controller()
export class AppController {
constructor(private readonly appService: AppService,
private readonly configService: ConfigService) {}
@Get()
getHello(): string {
const testId = this.configService.get<string>('test_id');
return this.appService.getHello() + ', TEST ID:' + testId;
}
}
あとはデプロイして実行してみてTEST IDが返却されたらOKです。
$ nest build
$ sls deploy
~ 中略 ~
$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/
Hello World!, TEST ID:dev_test
環境削除
念のためAWSに作成した環境の削除も記載しておきます。
$ sls remove
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
.....................
Serverless: Stack removal finished...
Serverless: [LayersPlugin]: Removing layer version: 2
Serverless: [LayersPlugin]: Removing layer version: 1
Serverless: [LayersPlugin]: Layers removal finished.
$ aws s3 rb s3://nestjs-serverless-test-bucket --force
delete: s3://nestjs-serverless-test-bucket/serverless/nestjs-serverless-test/dev/layers/nestjs-serverless-test-dev.zip
delete: s3://nestjs-serverless-test-bucket/serverless/nestjs-serverless-test/dev/layers/package.json
remove_bucket: nestjs-serverless-test-bucket
Author And Source
この問題について(Serverless NestJS), 我々は、より多くの情報をここで見つけました https://qiita.com/YutaSaito1991/items/b90440b01f6ead27ff22著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .