Как использовать TypeScript для AWS Lambda за 3 шага
Серия AWS Lambda / NodeJS (TypeScript)
- Как использовать TypeScript для AWS Lambda за 3 шага s
- Модульный тест и тест интеграции для AWS Lambda / NodeJS в TypeScript
Ситуация
Когда мы используем NodeJS в качестве среды выполнения для AWS Lambdas, JavaScript является языком по умолчанию. Однако из-за отсутствия проверки ввода в JavaScript время от времени ошибочный код развертывается в Lambda. Например, такая небольшая опечатка:
exports.lambdaHandler = async (event, context) => { const queries = event.queytStringParameters; // ... }
Мы хотим получить queryStringParameters
, но queries
заканчивается undefined
в результате невнимательности.
Цель
Мы хотим использовать TypeScript для написания обработчиков лямбда. С TypeScript у нас будут следующие преимущества:
- Подсказки автозавершения кода при программировании
- Проверка ошибок времени компиляции, чтобы избежать избыточных развертываний
Это несложно, в этой статье представлены 3 шага для выполнения этой работы.
Подготовка
Прежде чем пройти три шага, давайте создадим классический лямбда-проект с помощью SAM CLI:
sam init
После указанной выше команды мы получим папку с этими файлами:
├── README.md ├── events │ └── event.json ├── hello-world │ ├── app.js │ ├── package.json │ └── tests │ └── unit │ └── test-handler.js └── template.yaml
Затем мы начнем переводить этот JS-пакет в TS-пакет.
Шаг 1. Добавьте зависимость TypeScript
В package.json
добавьте следующие коды:
"scripts": { "compile": "tsc" }, "devDependencies": { "aws-sdk": "^2.655.0", "@types/aws-lambda": "^8.10.51", "@types/node": "^13.13.5", "typescript": "^3.8.3" }
- scripts / compile: это будет использоваться для компиляции кода TypeScript в JavaScript.
- devDependencies: поскольку это только для разработки, нам не нужно добавлять пакеты в блок
dependencies
- aws-sdk: в зависимости от того, используете ли вы AWS SDK в лямбда-выражении.
- @ types / aws-lambda: это очень важно для проверки завершения кода и ввода.
- @ types / node: нам нужен этот пакет для встроенных типов
- машинописный текст: откуда
tsc
Шаг 2. Добавьте tsconfig.json
{ "compilerOptions": { "module": "CommonJS", "target": "ES2017", "noImplicitAny": true, "preserveConstEnums": true, "outDir": "./built", "sourceMap": true }, "include": ["src-ts/**/*"], "exclude": ["node_modules", "**/*.spec.ts"] }
Компилятору TypeScript требуется tsconfig.json
, чтобы понять, как преобразовать TypeScript в JavaScript.
- модуль: CommonJS здесь подойдет
- target: применение ES2017 сохранит синтаксис
async
иawait
вместо преобразования их вPromise
код. Поскольку мы используем Node12 в качестве среды выполнения, функция Lambda поддерживает интерпретацию синтаксиса. Между тем, сохранениеasync
иawait
делает код чистым и коротким. - noImplicitAny: рекомендуется иметь. Компилятор выдаст ошибку, если переменная объявлена без типа
- preserveConstEnums: больше похоже на синтаксический сахар, но я хотел бы оставить его включенным, потому что он может сохранять
enum
классы в коде JavaScript в формеobject
, что помогает понять код JavaScript. - outDir: любая папка, которую вы хотите установить в качестве вывода компиляции.
- sourceMap: это необязательно
Шаг 3. Измените код
Сначала создайте папку src-ts
и переместите app.js
в эту папку.
app.js
теперь выглядит так:
exports.lambdaHandler = async (event, context) => { const queries = JSON.stringify(event.queytStringParameters); return { statusCode: 200, body: `Queries: ${queries}` } };
Создадим app.ts
и заменим его:
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda"; export const lambdaHandler = async ( event: APIGatewayProxyEvent ): Promise<APIGatewayProxyResult> => { const queries = JSON.stringify(event.queryStringParameters); return { statusCode: 200, body: `Queries: ${queries}` } }
Поскольку этот файл TypeScript будет скомпилирован в папку built
, нам также необходимо изменить поле Handler
в template.yaml
, чтобы ресурс lambda
мог найти код по правильному пути:
Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello-world/built Handler: app.lambdaHandler
Мы добавляем путь built
к папке hello-world
, чтобы AWS Lambda могла правильно найти обработчик.
Теперь каталог выглядит так:
├── README.md ├── hello-world │ ├── built │ │ ├── app.js │ │ └── app.js.map │ ├── package-lock.json │ ├── package.json │ ├── src-ts │ │ ├── app.ts │ │ └── tests │ └── tsconfig.json ├── samconfig.toml └── template.yaml
Развертывание и тестирование
cd hello-world npm install npm run compile cd .. sam deploy --guided
После успешного развертывания мы увидим функцию Lambda в консоли AWS следующим образом:
И мы должны иметь возможность протестировать лямбда-функцию с помощью следующей команды:
▶ curl https://[API_ID].amazonaws.com/Prod/hello\?weather\=sunny Queries: {"weather":"sunny"}
Заключение и следующий шаг
Пример кода можно найти по адресу: https://github.com/zijing07/aws-lambda-nodejs-ts
Я нахожу это действительно освежающим после использования поддержки TypeScript для моих функций Lambda. С одной стороны, это могло бы сэкономить мне массу времени на поиск в документации API имени метода или списка параметров. С другой стороны, tsc
также помогает мне обнаруживать любые потенциальные проблемы перед развертыванием.
В следующей статье я расскажу о том, как проводить локальные интеграционные тесты на Lambda-функциях.