Без API не обходится ни одно веб-приложение. Для их разработки используются разные методы. Сейчас, например, набирает популярность бессерверный подход — он экономичный, масштабируемый и относительно простой. Как ведущий провайдер бессерверных вычислений Amazon Web Services (AWS) вносит огромный вклад в бессерверную разработку. Здесь мы обсудим общие концепции реализации API с помощью AWS Lambda и других сервисов AWS. AWS Lambda — это сервис AWS, который отвечает за выполнение определенных функций в ответ на триггеры, то есть события в приложении. Это могут быть HTTP-вызовы, события в других сервисах AWS, например S3, Kinesis или SNS, или повторяющиеся запланированные события. Функции выполняются в эфемерных контейнерах, подготовкой и масштабированием которых занимается AWS, так что разработчики избавлены от хлопот, связанных с инфраструктурой. Еще одно привлекательное преимущество — оплата по мере использования. Вы платите только за общее время выполнения функций и не тратитесь в периоды простоя. Конечно, у Lambda, как и у любого другого сервиса, есть свои ограничения. Он не подходит для некоторых задач вроде очень длительных заданий, интенсивных вычислений или процессов, где мы должны контролировать среду выполнения. Но для реализации API сервис AWS Lambda обычно подходит идеально. AWS API Gateway — это сервис, с помощью которого разработчики создают конечные точки (HTTP endpoints), управляют ими и сопоставляют их с определенными ресурсами AWS, а также настраивают кастомные домены, механизмы авторизации, кэширование и другие фичи. API Gateway — это основная часть бессерверного API, потому что отвечает за связь между определенным API и функцией, обрабатывающей запросы к этому API. API Gateway включает множество функций и интеграций. В какой-то момент в Amazon поняли, что разработчикам, которые используют бессерверные вычисления, обычно не нужно столько всего. Скорее, они предпочли бы в целом упростить процесс реализации. Наверное, поэтому в конце 2019 года AWS объявили о новых HTTP API, облегченной версии API Gateway, которая существенно упрощает разработку, повышает производительность и снижает расходы для бессерверных API. Несмотря на свою простоту, HTTP API поддерживают такие важные фичи, как настройка CORS для всех конечных точек, интеграция JWT, кастомные домены и соединения с VPC. Чтобы разобраться с главными принципами реализации бессерверных API, рассмотрим лаконичный пример простого приложения виртуальной доски, состоящий из двух конечных точек: POST для записи сообщений и GET для извлечения трех последних сообщений. Рассмотрим и другие возможные функции (параметры пути, CORS и авторизаторы), но постараемся не усложнять финальную реализацию. Наш проект будет полностью бессерверным, поэтому используем AWS DynamoDB для хранения сообщений. Эта база данных отвечает принципам бессерверной архитектуры — простота использования и оплата только за запросы. DynamoDB — это база данных NoSQL «ключ-значение» от AWS, где данные хранятся на серверах AWS и полностью управляются Amazon. Для реализации вам понадобится аккаунт AWS, а также установленный и настроенный фреймворк AWS Serverless Application Model (SAM). SAM — это инструмент для создания, обновления и администрирования бессерверных приложений и всех ресурсов, которые нужны ему для работы. С AWS SAM мы не создаем каждый сервис вручную на веб-консоли — мы просто описываем все, что нам нужно, в специальном файле шаблона.
После установки CLI переходим в нужный каталог и выполняем команду: $ sam init -r nodejs12.x -n whiteboard
Инициализация нового проекта Выбираем первую опцию и нажимаем Quick Start from Scratch (Быстрый запуск с нуля). Создается каталог нашей доски с минимумом установочных файлов. Сначала открываем файл template.yml и удаляем все, что находится под разделом Resources. Прежде чем перейти к самому API, создаем дополнительные ресурсы. Определяем таблицу DynamoDB, где будут храниться сообщения: Объявление таблицы DynamoDB AWS создает таблицу DynamoDB, где атрибутом partKey будет ключ партиции, одинаковый для всех записей, а атрибутом createdAt будет ключ диапазона для сортировки по метке времени. Можно добавить в записи другие ключи и значения, но определять их необязательно. Теперь в том же файле, сразу под предыдущим определением, объявим HTTP API, с которым будут связаны все будущие конечные точки и функции. Объявление HTTP API Это очень короткое и простое определение — название этапа и конфигурация CORS, которые, впрочем, необязательны. Видите, каким простым и лаконичным может быть создание API? При необходимости, конечно, можно добавить самые разные свойства, например ссылку на функцию авторизации, определение домена, параметры логирования и другие. Наконец, определив все API, давайте объявим две функции, связанные с конкретными конечными точками. Объявление обработчиков для запросов POST и GET Тут все понятно: две функции, одна из которых будет вызываться при запросе POST к пути /messages, а другая — при запросе GET к тому же пути. У обеих функций есть ограничения на 128 МБ оперативки и пятисекундный таймаут. Код функций находится в файлах postMessage.js и getMessage.js в каталоге /src/handlers/. Создадим их прямо сейчас. (Мы предоставили полный доступ к DynamoDB в разделе Policies каждой функции, чтобы упросить код. В реальном проекте доступ нужно будет настроить более тонко). Идем в каталог /src/handlers и создаем файлы со следующим содержимым: postMessage.js Код обработчика запросов POST Эта функция будет выполняться в ответ на запросы POST. Она вычленяет из тела запроса автора и текст и сохраняет эти данные в базе данных. Еще она заполняет атрибут partKey одинаковым значением для всех записей. Обычно это не лучший метод, но для нашего примера подходит, потому что позволяет выполнять сортировку по ключам диапазона среди всех элементов с одинаковым ключом партиции. Кстати, DynamoDB всегда ожидает строку, даже если тип атрибута — число. getMessages.js Код обработчика запросов GET В этой функции мы сначала получаем записи, у которых partKey равен board, потом задаем для ScanIndexForward значение false, чтобы последние сообщения отображались сверху, и наконец с помощью свойства Limit указываем, что хотим увидеть только три сообщения. Деплоить с AWS SAM легко — достаточно одной команды с несколькими введенными значениями. Переходим в root-каталог проекта и выполняем команду: Команда развертывания Нас попросят ввести имя приложения и выбрать регион AWS, а еще подтвердить несколько действий: 
Указание и подтверждение параметров После подтверждения параметров запускается развертывание и создаются ресурсы. На это уйдет не больше минуты. 
Список создаваемых ресурсов их статусы Когда процесс завершится, открываем веб-консоль AWS в браузере, переходим к сервису API, находим только что созданный API и копируем URL к корневому эндпоинту нашего API. 
URL для конечной точки root API Давайте напишем на доске несколько сообщений используя, как и большинство из нас, утилиту curl. В следующей команде замените плейсхолдеры своими данными. Выполнение запроса POST в curl Отправляем несколько запросов с разными сообщениями. Если все нормально, в консоли отобразится Message posted on board! (Сообщение опубликовано на доске) без ошибок. Чтобы извлечь последнее сообщение, выполним простую команду, даже короче предыдущей: Выполнение запроса GET в curl Вот и все. Мы создали простой HTTP API с AWS Lambda и AWS SAM. Конечно, в реальном проекте нужно будет больше функций и конфигураций, но принцип будет тот же: определяем ресурсы, определяем конфигурации, пишем код и запускаем деплой. Будет разумно организовать мониторинг — особенно для бессерверных приложений, где легко запутаться с дебагом и трейсингом. Можно подключить мониторинг Thundra к только что созданным функциям Lambda (см. краткое руководство). После подключения Thundra вам нужно будет инструментировать функции Lambda postMessage и getMessages, чтобы просмотреть подробную информацию о каждом вызове и получить общую картину приложения. Выбираем функции в списке, нажимаем сначала кнопку Instrument, а затем OK. 
Подтверждение инструментирования функции Lambda Пробуем сделать несколько запросов к API, возвращаемся на дашборд Thundra, нажимаем на имя функции и выбираем вызовы из списка. Здесь мы видим время, производительность, входные и выходные данные функции и т. д. Это очень полезно при отладке API в реальных проектах. 
Сведения об одном вызове Если вы используете бессерверные вычисления в сложных проектах с разными сервисами AWS или других вендоров, вам определенно пригодится функция Unique Tracing, которая существенно упрощает устранение неполадок и отладку приложения. С помощью HTTP API с AWS Lambda можно создавать высокопроизводительные и экономичные API. Хоть это и облегченная версия API Gateway REST API, она обладает всем необходимым функционалом и покрывает 90% нужд разработчиков. HTTP API не поддерживают некоторые полезные функции, вроде кэширования, валидации схем и трансформации ответов.  Кэширование вам, скорее всего, не пригодится, потому что HTTP API работают гораздо быстрее старых REST API, а валидацию и трансформацию можно выполнять на уровне кода функции.
Если у ваших разработчиков нет других причин отказаться от HTTP API, можете с уверенностью их использовать. Обычно бессерверная транзакция начинается с вызова API, а отслеживать асинхронный поток событий не так-то просто. В таких ситуациях используйте комплексную функцию распределенного трейсинга в Thundra. Thundra предоставляет 250 тысяч запросов в месяц бесплатно — вполне достаточно для маленьких проектов или стартапов. Редактор