Help us understand the problem. What is going on with this article?

Ionic/Angularと相性抜群のNodeフレームワーク「NestJS」をLambdaで公開する方法

More than 1 year has passed since last update.

Ionic/Angularでは、TypeScriptを採用しているので、APIからのレスポンスを型定義します。で、常々、「バックエンドでも型定義をして、それをフロントエンドと共有できたら最強では」と思っていたのですが、先日Angularから強い影響を受けたTypeScript製Node.jsフルスタックフレームワーク「NestJS」の存在を教えてもらいました。

どのようなものかは 【Node.js】TypeScript製Node.jsフルスタックフレームワーク Nest 導入編をご覧ください。

これを採用したことにより、今はInterfaceをフロントエンド・バックエンドで共有できていて、とても快適に開発を進めていたのですが、「いざ公開」の段になって、Lambda + API Gatewayで苦戦したのでまとめておきます。

Lambdaで公開する手順

Serverless Framework経由にLambdaに公開する設定については https://github.com/rdlabo/serverless-nestjs でパッケージ一式で公開しています。

既存のプロジェクトに設定する方法

1. Serverless FrameworkとLambda用のパッケージを追加

$ npm install aws-lambda aws-serverless-express express

2. Lambda関数用の src/index.ts を作成

src/index.ts
import { Context, Handler } from 'aws-lambda';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Server } from 'http';
import * as serverless from 'aws-serverless-express';

const express = require('express')();
let cachedServer: Server;

function bootstrapServer(): Promise<Server> {
  return NestFactory.create(AppModule, express)
    .then(app => app.enableCors())
    .then(app => app.init())
    .then(() => serverless.createServer(express));
}

export const handler: Handler = (event: any, context: Context) => {
  if (!cachedServer) {
    bootstrapServer().then(server => {
      cachedServer = server;
      return serverless.proxy(server, event, context);
    });
  } else {
    return serverless.proxy(cachedServer, event, context);
  }
};

通常公開と違い、Lambdaの関数としてNestJSを利用するので、専用の公開ファイルを用意する必要があります。

3. Serverless Framework設定ファイルの serverless.yml を追加

serverless.yml
service: serverless-nestjs

provider:
  name: aws
  runtime: nodejs8.10
  region: ap-northeast-1

package:
  exclude:
    - .git/**
    - src/**
    - test/**
    - nodemon.json
    - README.md

functions:
  index:
    handler: dist/index.handler
    events:
    - http:
        cors: true
        path: '/'
        method: any
    - http:
        cors: true
        path: '{proxy+}'
        method: any

regionは、東京で設定します。また、先ほど作成したLambda用関数を、Lambdaに紐つけるために、functionsを設定します。NestJS内でのルーティングをLambda経由で反映させるために path: {proxy+} をトップディレクトリとは別に設定します。

デプロイ方法

$ npm run prestart:prod
$ sls deploy

npm run prestart:prodを実行すると、src/フォルダからtscを使ってdistファイルを生成します。そのあと、Serverless Frameworkのコマンドを叩いてデプロイを実行してください。

うまくいくと、 https://mmjdx4zxmc.execute-api.ap-northeast-1.amazonaws.com/dev/ ができます。

おまけ

IonicとNestJSのInterfaceをどうやって共有するかについては、こちらで「どうしたらいいかなぁ」とツイートしておりますのでご参考になりましたら幸いです。これがベストプラクティスだ!!っていうのありましたらコメントかリプライでご教示いただけましたら幸いです。
https://twitter.com/rdlabo/status/1031760620654276608

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした