Як зробити будь-який додаток NodeJS без сервера

Я сподіваюся, що ви любите Serverless так само, як і я, тому що це ще одна публікація на цю тему.

Тепер, якщо ми говоримо про простий REST API без сервера, у налаштуваннях AWS: Lambda + API Gateway досить очевидно.

Але як щодо інших (мікро) послуг, які може мати ваш сервіс? Ви знаєте, це не найкраща ідея, щоб увесь код вашої програми об'єднати в єдину монолітну функцію AWS Lambda.

Змагання

Ми хочемо легко розгортати прикладні модулі як серверні мікросервіси, яким також потрібно спілкуватися один з одним. Переважно, зв'язок між службами повинен регулюватися деяким ACL.

Спроба 1. Шлюз API

Це перша думка, що мені випала, коли я намагався вирішити проблему: просто відкрийте всі мікросервіси через шлюз API. Проблема полягає в тому, що… Створені API є загальнодоступними.

Чому це проблема? Наприклад, ми не хочемо, щоб послуга виставлення рахунків піддавалася впливу всього світу, навіть якщо доступ обмежений за допомогою певного дозволу.

Ну, ви можете зробити API приватним, але політики безпеки досить обмежені:

Ви можете використовувати політику щодо ресурсів шлюзу API, щоб дозволити безпечному виклику вашого API:
* користувачів із зазначеного облікового запису AWS
* вказані діапазони IP-адрес джерела або блоки CIDR
* вказані віртуальні приватні хмари (VPC) або кінцеві точки VPC (у будь-якому обліковому записі)

Це робить проблематичним контроль за зв’язком між такими службами. Єдиний спосіб зробити це - введення служб в окремі VPC, занадто багато роботи.

Спроба 2. Лямбда

Чому ми просто не розмістимо кожен мікросервіс в окрему AWS Lambda? Чи вирішить це проблему?

Так, насправді це буде мікросервіс без сервера, і ви зможете використовувати політику IAM для налаштування доступу між службами, але… Це не просто.

Я знаю, що зараз цілком нормально функціонувати як крихітна функція. І якщо ваша служба має більше 1 кінцевої точки / методу / функції, вважати нормальним розгортати її як кілька лямбда.

Я розумію його переваги, але ви жертвуєте простотою обслуговування та розвитку. Крім того, мені дуже не подобається ідея розгортання служби у вигляді набору функцій Lambda. Уявіть, кілька окремих функцій, що стосуються виставлення рахунків? Це вже не обмежений контекст. Хоча є випадки, коли така деталізація може бути корисною, але це рідкісний випадок.

Спроба 3. Жирна лямбда

Чи можемо ми реально розгорнути набір кінцевих точок як єдину лямбда (звичайно, не використовуючи шлюз API)?

Якби ми могли це зробити, ми отримали б усі переваги попереднього варіанту, але ми також змогли б вибрати деталізацію наших підрозділів розгортання.

Мені так хочеться: кожен розгорнутий сервіс повинен бути простим простим старим об'єктом JS з методами. Цього досить тривіально досягти, додавши кілька рядків коду клею між вашим об’єктом та AWS Lambda.

Ось моя реалізація цього: aws-rpc. Цей модуль nodejs відкриває функцію lambdaHandler, де ви просто передаєте об'єкт, і він автоматично піддається впливу всіх, хто має можливість отримати доступ до Lambda:

import {lambdaHandler} з 'aws-rpc';
імпорт {TestServiceImpl} з './TestServiceImpl';
// це ваш блок розгортання
// це те, що ви вказали як функцію обробника Lambda
export const handler = lambdaHandler (новий TestServiceImpl ());

Тепер ви можете просто розгорнути «обробник» як AWS Lambda. Ось як ви посилаєтесь на його методи:

імпортувати {TestService} з './TestService';
const client = очікуємо createClient  ("LambdaName", "test");
console.log (чекайте client.test ());

Зауважте, що для того, щоб мати змогу генерувати методи для об'єкта клієнтського заглушки, вам потрібно передати всі назви методів createClient, як ми це робили в прикладі.

Це потрібно, оскільки JS не має жодної інформації про виконання інтерфейсів TypeScript. Я міг би реалізувати це за допомогою абстрактних класів, але мені це не подобається ¯ \ _ (ツ) _ / ¯.

Бонус! Ви можете запустити все це локально!

Я вважаю, що дуже важливо, щоб ваше місцеве середовище розвитку було максимально комфортним. Ось чому я також додав можливість запускати службу та клієнта локально, не розгортаючи нічого на AWS (див. Функції runService і createClient). Приклади див. У сховищі на GitHub.

Підсумок

Це дуже легко загубитися в послугах, які пропонують хмарні провайдери, і переобладнати вашу інфраструктуру.

Я завжди вибираю найбільш просте і чітке рішення, про яке я можу придумати. Крім того, завжди пам’ятайте, що багато методів і практик можна повторно використовувати з інших платформ (ідея жирового NodeJS Lambda натхненна так званими жировими банками з світу Java).

Якщо вам сподобалась ця тема, ознайомтесь і з цими:

  • Ви повинні навчитися робити найкращу архітектуру без сервера
  • Як створити безкоштовний CI / CD конвеєр без сервера: 3 простих прикладу
  • Як легко копіювати DynamoDB в регіонах
  • Як зробити багаторегіональну заявку (і заплатити нуль)
  • Зробіть будь-який сервер Java-додатків без сервера

Коментарі, лайки та акції високо оцінені. Ура!