Структурирование бессерверных проектов

Полное руководство по настройке проектов с использованием бессерверной платформы

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

Этот пост написан с использованием python и AWS, хотя вы сможете без проблем адаптировать его для работы с node.js или любым другим языком.

Требования

Вот некоторые из основных требований, которые мне нужно было поддерживать при настройке моего проекта:

  • Разделение кода на логические модули
  • Совместное использование зависимостей между модулями
  • Совместное использование кода между модулями
  • Разделение конечных точек по ресурсам в модулях
  • Поддержка автономного тестирования конечных точек

Обзор

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

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

При определении того, как разделить ваши Сервисы, старайтесь в целом группировать облачные ресурсы по их бизнес-домену, при этом отдельно отделяя облачные ресурсы, которые вы часто развертываете (например, код, функции), от ресурсов, которые следует развертывать нечасто и осторожно (например, базы данных, VPC).

Вступление

Общие пакеты

Непосредственно в нашей папке src у нас сначала есть любой код, который необходимо совместно использовать во всем приложении или между различными первичными модулями. Это просто стандартные пакеты Python, но мы не будем вдаваться в подробности их создания в этой статье.

Слои

На этом же уровне у нас также есть каталог, содержащий наши слои. Лямбда-слои используются для включения общих зависимостей или кода между несколькими лямбда-функциями без необходимости включать их в наш пакет развертывания. Это ускорит будущую разработку, а также поможет вам избежать ошибок, которые могут возникнуть при установке и упаковке зависимостей с вашим кодом. Ниже приведен пример того, как вы можете определять слои и настраивать свои функции для использования их в вашем serverless.yml.

Чтобы использовать слой с функцией в том же сервисе, используйте CloudFormation Ref. Имя вашего слоя в шаблоне CloudFormation будет вашим именем слоя TitleCased (без пробелов) и будет добавлено LambdaLayer в конец.

Для получения дополнительной информации об использовании бессерверных слоев посетите:



Основные модули (или службы)

Далее у нас есть каталог модулей. В нем наш код разделен на основные модули (или, как их называют бессерверные команды, - на сервисы). Как мы уже упоминали ранее, эти модули разделены на основе бизнес-домена и предназначены для предотвращения разрушения всей вашей платформы одним развертыванием. Каждый основной модуль содержит собственный файл serverless.yml и представляет собой отдельный бессерверный проект. Это означает, что вы будете развертывать и тестировать каждый модуль независимо друг от друга. Из-за этого вы хотите убедиться, что вы не слишком агрессивны с разделением кода на этом уровне.

Для кода, который просто нужно разделить по ресурсам, у нас есть подмодули, которые мы коснемся дальше.

Подмодули

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

Каждый подмодуль довольно прост, содержит только конечные точки и связанную с ними логику. Обычно я называю эти файлы functions.yml и handler.py.

Типичный файл functions.yml будет выглядеть примерно так:

Как видите, даже несмотря на то, что файл handlers.py находится в том же каталоге, что и файл functions.yml, вам все равно нужно ссылаться на его функции, используя его путь относительно корневой каталог основных модулей . Это потому, что во время выполнения все ваши функции импортируются в ваш serverless.yml и запускаются оттуда.

handlers.py содержит фактический код для этих конечных точек. Рекомендуется разделить все повторно используемые части в пакет, который можно использовать во всем приложении (например, функцию помощников для синтаксического анализа тела). Это пример того, как будут выглядеть заглушки функций для события httpApi, но это будет зависеть от того, что запускает ваши функции.

Автономное тестирование / развертывание

Для поддержки автономного тестирования конечных точек (с использованием serverless-offline) и развертывания в AWS вам необходимо, чтобы ваши зависимости и модули были установлены локально (в идеале с использованием venv) и на вашем уровне в каталоге lib/requirements/python/lib/python3.8/site-packages. Вот и пример основного сценария настройки, который позаботится об этом за вас.

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