Serverless функции на JavaScript: AWS Lambda от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Что такое Serverless и AWS Lambda?

Serverless (бессерверные вычисления) — это модель облачных вычислений, при которой разработчик полностью абстрагируется от управления серверной инфраструктурой. Вы просто пишете код, загружаете его в облако, и провайдер (AWS, Google Cloud, Azure) автоматически запускает его в ответ на события, масштабируя ресурсы по требованию. Вы платите только за фактическое время выполнения кода (и количество запросов).

AWS Lambda — это флагманский serverless-сервис от Amazon Web Services. Он позволяет запускать код на различных языках, включая JavaScript (Node.js), без необходимости выделять и обслуживать серверы. Lambda идеально подходит для обработки HTTP-запросов (через API Gateway), фоновых задач, обработки файлов из S3, реакций на изменения в базе данных DynamoDB и многих других сценариев.

В этой статье мы разберём AWS Lambda на JavaScript от А до Я: от создания первой функции до её деплоя, мониторинга и оптимизации.

Основная часть: Создание и управление Lambda-функциями на Node.js

1. Создание первой Lambda-функции

Перейдите в консоль AWS Lambda и нажмите "Создать функцию". Выберите опцию "С нуля". Укажите имя (например, my-first-lambda) и выберите среду выполнения Node.js 20.x (или последнюю стабильную версию).

Базовая структура функции на Node.js выглядит так:

exports.handler = async (event, context) => {
    // event - данные, которые передаются в функцию (например, HTTP-запрос)
    // context - информация о среде выполнения (например, ID запроса)

    console.log('Получено событие:', JSON.stringify(event, null, 2));

    // Ваша бизнес-логика
    const response = {
        statusCode: 200,
        body: JSON.stringify({
            message: 'Hello from Lambda!',
            input: event
        }),
    };

    return response; // AWS Lambda ожидает возврата значения
};

В этом простом примере функция принимает событие и возвращает JSON-ответ. Если функция вызывается через API Gateway, event будет содержать HTTP-метод, заголовки, тело запроса и т.д.

Важно: Всегда используйте async/await для работы с асинхронными операциями (запросы к базе данных, API). Если функция не асинхронная, она должна возвращать Promise или использовать callback.

2. Триггеры и интеграции

Сила Lambda раскрывается через триггеры — события от других сервисов AWS, которые запускают вашу функцию. Рассмотрим три самых популярных варианта на JavaScript.

2.1. HTTP-запросы через API Gateway

Это самый распространённый сценарий для создания REST API. Вы прикрепляете к Lambda триггер API Gateway. В этом случае event будет содержать структуру HTTP-запроса. Пример обработки:

exports.handler = async (event) => {
    const httpMethod = event.httpMethod;
    const path = event.path;
    const queryParams = event.queryStringParameters || {};
    const body = event.body ? JSON.parse(event.body) : {};

    console.log(`Метод: ${httpMethod}, Путь: ${path}`);

    if (httpMethod === 'GET' && path === '/hello') {
        return {
            statusCode: 200,
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ message: `Привет, ${queryParams.name || 'мир'}!` })
        };
    }

    return {
        statusCode: 404,
        body: JSON.stringify({ error: 'Not Found' })
    };
};

2.2. Обработка файлов из S3

Lambda может автоматически срабатывать при загрузке или удалении файлов в корзине S3. Это идеально для создания миниатюр изображений, конвертации видео или индексации данных.

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    // event содержит информацию о созданном объекте S3
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));

    console.log(`Файл загружен: ${bucket}/${key}`);

    // Пример: читаем файл
    const params = { Bucket: bucket, Key: key };
    const data = await s3.getObject(params).promise();
    const content = data.Body.toString('utf-8');

    console.log('Содержимое файла:', content);

    return { statusCode: 200, body: 'File processed' };
};

2.3. Обработка событий из DynamoDB Streams

Если вы используете DynamoDB, вы можете настроить Stream, который будет вызывать Lambda при каждой вставке, обновлении или удалении записи. Это основа для создания реактивных приложений.

exports.handler = async (event) => {
    for (const record of event.Records) {
        // eventName: 'INSERT', 'MODIFY', 'REMOVE'
        console.log('Тип события:', record.eventName);
        console.log('Новые данные:', JSON.stringify(record.dynamodb.NewImage));
        console.log('Старые данные:', JSON.stringify(record.dynamodb.OldImage));
    }

    return `Обработано ${event.Records.length} записей.`;
};

3. Локальная разработка и тестирование

Писать код сразу в консоли AWS неудобно. Для локальной разработки используйте AWS SAM (Serverless Application Model) или Serverless Framework. Мы рассмотрим простой подход с npm-пакетом lambda-local.

Установите пакет глобально:

npm install -g lambda-local

Создайте локальный файл event.json с тестовыми данными:

{
  "httpMethod": "GET",
  "path": "/hello",
  "queryStringParameters": {
    "name": "PythonLib"
  }
}

Запустите функцию локально:

lambda-local -l index.js -h handler -e event.json

Этот подход позволяет быстро отлаживать код без необходимости каждый раз деплоить функцию в облако.

4. Деплой, мониторинг и лучшие практики

4.1. Деплой через AWS CLI

Упакуйте ваш код (включая node_modules) в ZIP-архив и загрузите его через CLI:

# Упаковка
zip -r function.zip .

# Деплой
aws lambda update-function-code --function-name my-first-lambda --zip-file fileb://function.zip

                
                

Блоги

Рекомендаций по книгам