Пример Lambda AWS | DynamoDB, приложение API Gateway S3 FullStack

Вы, наверное, слышали о термине полный стек в какой-то момент и задавались вопросом, что, черт возьми, оно могло означать. Вопреки тому, что приходит на ум изначально, этот термин не имеет ничего общего со структурой данных. Стек относится к системе, состоящей из множества технологий, работающих вместе для достижения желаемого поведения.

Для уточнения предположим, что мы создали веб-приложение на основе React, которое позволяет пользователю добавлять задачи в список дел.

Если бы мы обновили страницу, все задачи, добавленные в список дел, были бы потеряны.

Для любого клиентского приложения, если мы хотим, чтобы данные сохранялись за пределами сеанса пользователя, мы должны использовать какой-то бэкэнд. Сохраняя данные внутри базы данных на удаленном сервере и извлекая их после запуска приложения, пользователи могут безопасно обновлять страницу и / или закрывать браузер.

LAMP, хотя и выходит из строя, является типичным примером полнофункционального приложения. ЛАМПА означает:

  • L inux
  • A паче
  • M ySQL
  • P HP

Сегодня вы, скорее всего, увидите некоторые варианты стека MEAN.

  • M ongoDB
  • E xpress
  • Обычный
  • Нет оды

В следующей статье мы рассмотрим, как создать приложение с полным стеком, используя React, Node (Lambda), DynamoDB и API Gateway.

Мы начнем с создания базы данных, которая будет использоваться для хранения нашего списка задач.

aws dynamodb create-table --table-name ToDoList --attribute-definitions AttributeName=Id,AttributeType=S AttributeName=Task,AttributeType=S --key-schema AttributeName=Id,KeyType=HASH AttributeName=Task,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

Я хотел бы воспользоваться этой возможностью, чтобы прояснить функцию ролей в AWS. Роль определяет, на какую службу или пользователя вы хотите повлиять. Только после того, как вы прикрепите политики к роли, она ограничивает или предоставляет доступ к какому-либо ресурсу.

На следующих этапах мы создадим роль, которая позволит Lambda записывать и сканировать нашу таблицу DyanmoDB.

aws iam create-role --role-name lambda-role --assume-role-policy-document file://trusted_entity.json
aws iam put-role-policy --role-name lambda-role --policy-name dynamodb-access --policy-document file://set_policy.json

Затем мы создадим две лямбда-функции. Первый будет использоваться для сканирования таблицы для поиска списка задач, а второй будет использоваться для добавления новых задач в базу данных. Мы указываем имя нашей таблицы как переменную среды и импортируем DocumentClient для выполнения запросов к экземпляру DynamoDB.

Если вы хотите использовать внешние библиотеки, лямбда-функции необходимо загружать в формате .zip.

zip function.zip get.js
aws lambda create-function --function-name get-tasks --zip-file fileb://function.zip --runtime nodejs8.10 --role arn:aws:iam::084696551378:role/lambda-role --handler get.getAllTasks --environment Variables={TABLE_NAME=ToDoList}
zip function2.zip post.js
aws lambda create-function --function-name add-task --zip-file fileb://function2.zip --runtime nodejs8.10 --role arn:aws:iam::084696551378:role/lambda-role --handler post.addTask --environment Variables={TABLE_NAME=ToDoList}

API Gateway дает нам возможность выполнять функции Lambda из клиента. Для вас, новичков, API означает интерфейс прикладного программирования. Как следует из названия, API - это конечная точка (то есть URL-адрес), к которой обращается код приложения. Каждый раз, когда вы вводите URL-адрес веб-страницы, вы фактически запрашиваете с сервера набор файлов HTML, CSS и Javascript. Затем эти файлы интерпретируются браузером таким образом, чтобы сделать их более удобочитаемыми. Серверы могут обслуживать и обслуживают другие формы данных, наиболее известной из которых является JSON. Например, вы можете разработать приложение для хоккейного пула, которое выполняет вызов API для получения последней статистики. Вместо того, чтобы запрашивать всю веб-страницу, мы можем получить всю необходимую информацию из объекта JSON.

aws apigateway create-rest-api --name 'To Do List'

Нам нужен идентификатор ресурса, связанный с корневым маршрутом (/).

aws apigateway get-resources --rest-api-id vaz7da96z6

В этом примере мы будем использовать один и тот же маршрут для сканирования и записи в базу данных. Однако в большинстве реальных сценариев вы использовали бы несколько маршрутов в соответствии с REST.

aws apigateway create-resource --rest-api-id vaz7da96z6 --parent-id begaltmsm8 --path-part tasks

Не вдаваясь в подробности, REpresentational State Transfer или REST описывает, как внутренний сервер и клиент должны взаимодействовать. По сути, мы не хотим, чтобы они были тесно связаны. Теоретически внутренний сервер должен иметь возможность использовать несколько приложений. Например, следуя парадигме REST, у вас может быть сервер, связанный с доменом cutepuppies.com с помощью следующих маршрутов.

Каждый HTTP-запрос связан с определенным методом. Каждый раз, когда вы заходите на веб-страницу, вы фактически создаете запрос с помощью метода GET. Для нашего API всякий раз, когда мы получаем запрос GET, мы возвращаем список задач из нашей таблицы. С другой стороны, запросы POST используются всякий раз, когда вы хотите отправить данные на удаленный сервер. Мы будем использовать запросы POST для отправки и сохранения задач в нашей базе данных.

aws apigateway put-method --rest-api-id vaz7da96z6 --resource-id 6sxz2j --http-method GET --authorization-type NONE
aws apigateway put-method --rest-api-id vaz7da96z6 --resource-id 6sxz2j --http-method POST --authorization-type NONE

По соглашению, всякий раз, когда HTTP-запрос к удаленному серверу оказывается успешным, он отвечает кодом состояния 200.

aws apigateway put-method-response --rest-api-id m9r6tlx76g --resource-id qhxwgr --http-method GET --status-code 200
aws apigateway put-method-response --rest-api-id m9r6tlx76g --resource-id qhxwgr --http-method POST --status-code 200

Хотя в интерфейсе командной строки есть возможность сопоставлять конечные точки с лямбда-функциями, гораздо проще использовать консоль.

Чтобы сервисы правильно работали вместе, мы должны добавить ответы на интеграции.

aws apigateway put-integration-response --rest-api-id m9r6tlx76g --resource-id qhxwgr --http-method GET --status-code 200 --selection-pattern ""
aws apigateway put-integration-response --rest-api-id m9r6tlx76g --resource-id qhxwgr --http-method POST --status-code 200 --selection-pattern ""

Мы не сможем выполнять вызовы API из нашего приложения, если не включим совместное использование ресурсов между источниками (CORS). CORS - это механизм, который использует дополнительные заголовки HTTP, чтобы сообщить браузеру, что веб-приложение должно иметь разрешение на доступ к выбранным ресурсам с сервера из другого источника.

После включения CORS мы можем развернуть API.

aws apigateway create-deployment --rest-api-id vaz7da96z6 --stage-name api

Если не изменить с помощью CloudFront, URL-адрес API будет иметь следующий формат.

‹rest-api-id›. ‹region› .amazonaws.com / ‹stage› / ‹path›

Давайте проверим конечную точку, запустив curl.

curl -X GET https://m9r6tlx76g.execute-api.us-east-1.amazonaws.com/api/tasks
curl -X POST -d ‘{“task”:”Eat”}’ https://m9r6tlx76g.execute-api.us-east-1.amazonaws.com/api/tasks

Если вы работаете в Windows, вы можете использовать команду Powershell Invoke-WebRequest или установить Postman.

Теперь мы готовы приступить к написанию кода для нашего интерфейса. Для начала мы воспользуемся библиотекой create-react-app, не настраивая Webpack и Babel.

create-react-app full-stack

Обновите файл App.js, убедившись, что вы обновили оператор выборки, включив в него URL-адрес вашего API.

Запустите команду сборки, чтобы связать и минимизировать наш код Javascript.

npm run build

Создайте корзину S3 и скопируйте каталог сборки в нашу корзину.

aws s3 mb s3://full-stack-app.corymaklin.com
aws s3 cp --recursive build s3://full-stack-app.corymaklin.com

По умолчанию сегменты S3 являются частными. Если мы не обновим политику, чтобы предоставить пользователям доступ, они не смогут получить доступ к веб-сайту. Мы создадим файл .json со следующим содержимым. Убедитесь, что вы заменили ARN на тот, который связан с вашим ведром.

aws s3api put-bucket-policy --bucket s3://full-stack-app.corymaklin.com --policy file://policy.json

Войдите в консоль, если вы еще этого не сделали. Перейдите к своей корзине, затем выберите статический хостинг веб-сайтов на вкладке свойств.

Посетите веб-страницу, добавьте контент и попробуйте обновить страницу. Вы должны увидеть, что список дел сохраняется после сеанса.

Примечание. Если вы столкнетесь с какими-либо ошибками, попробуйте повторно развернуть API.