Com fer que una aplicació NodeJS no tingui servidor

Espero que us agradi Serverless tant com a mi, ja que es tracta d’una altra publicació sobre el mateix tema.

Si es tracta d’una API REST senzilla i sense servidor, la vostra configuració a AWS: Lambda + API Gateway és força evident.

Però, què tal altres serveis (micro) que pot tenir el vostre backend? Ja ho sabeu, embolicar tot el codi de l'aplicació en una sola funció monolítica AWS Lambda no és la millor idea.

El repte

Volem proporcionar mòduls d'aplicació simplement com a microserveis sense servidor que també han de comunicar-se entre ells. La comunicació entre serveis hauria d’estar regulada preferentment per un tipus d’ACL.

Intent 1. API Gateway

Aquest és el primer pensament que vaig tenir en intentar resoldre el problema: simplement exposar tots els microserveis a través de l’API Gateway. El problema és ... les API que s'estan creant són públiques.

Per què és un problema? Per exemple, no volem que hi hagi un servei de facturació disponible a tot el món, fins i tot si l’autorització restringeix l’accés.

Bé, podeu fer que l'API sigui privada, però les directrius de seguretat són força limitades:

Podeu utilitzar les polítiques de recursos de la passarel·la API per permetre que la vostra API sigui invocada de manera segura per:
* Usuari d'un compte AWS específic * Intervals d'adreces IP d'origen o blocs CIDR especificats * Núvols privats virtuals (VPC) o punts finals VPC especificats (en qualsevol compte)

Això fa que sigui bastant difícil controlar la comunicació entre aquests serveis. L’única manera de fer-ho aquí és col·locar serveis en VPC separats, cosa que suposa una feina excessiva.

Experiment 2. Lambda

Per què no posem cada microservei en un AWS Lambda separat? Resoldrà això el problema?

Sí, de fet és un microservei sense servidor i podeu utilitzar polítiques IAM per optimitzar l'accés entre serveis. Tot i això, no és "fàcil".

Sé que és bastant normal en aquests dies tenir un paper minúscul com a unitat de lliurament. En cas que el vostre servei tingui més d’un punt final / mètode / funció, està bé proporcionar-lo com a múltiples lambdas.

Entenc els avantatges, però sacrifiqueu la facilitat de manteniment i desenvolupament. A més, no m’agrada molt la idea d’exposar un servei com un conjunt de funcions Lambda. T’imagines diverses funcions diferents que s’ocupen de la facturació? Ja no és un context limitat. Tot i que hi ha casos en què aquesta granularitat pot ser útil, és un cas rar.

Proveu 3. Fat Lambda

En realitat, podem proporcionar una sèrie de punts finals com a Lambda (sense passarel·la API, és clar)?

Si poguéssim fer-ho, aprofitaríem tots els avantatges de l’opció anterior, però també podríem triar la granularitat de les nostres unitats de desplegament.

Això és el que vull veure: qualsevol servei que pugueu implementar hauria de ser un objecte JS senzill i antic amb mètodes. Això és bastant fàcil d'aconseguir afegint algunes línies de codi de cola entre l'objecte i AWS Lambda.

Aquí teniu la meva implementació: aws-rpc. Aquest mòdul nodejs exposa la funció lambdaHandler on només passeu un objecte i es posa automàticament a disposició de tots els usuaris que puguin accedir a la lambda:

importar {lambdaHandler} de 'aws-rpc'; Importeu {TestServiceImpl} des de './TestServiceImpl';
// aquesta és la vostra unitat de prova // això és el que especifiqueu com a funció lambda handler export const handler = lambdaHandler (new TestServiceImpl ());

Ara només podeu proporcionar el "controlador" com AWS Lambda. Com trucar als mètodes:

Importeu {TestService} des de './TestService';
client const = esperar a createClient ("LambdaName", "test"); console.log (espereu client.test ());

Tingueu en compte que per poder generar mètodes per a l'objecte de registre client, heu de passar tots els noms de mètodes a createClient com a l'exemple.

Això és necessari perquè JS no té informació en temps d'execució sobre les interfícies TypeScript. Podria implementar-lo amb classes abstractes, però no m'agrada ¯ \ _ (ツ) _ / ¯.

Bonificació Podeu fer-ho tot localment.

Crec que és molt important que el vostre entorn de desenvolupament local sigui el més còmode possible. Per aquest motiu, també he afegit la possibilitat d'executar el servei i el client localment sense haver de subministrar res per a AWS (vegeu funcions runService i createClient). Podeu trobar exemples al dipòsit de GitHub.

Resum

És molt fàcil de fer quan us perdeu dels serveis que ofereixen els proveïdors de núvol i reviseu la vostra infraestructura.

Sempre trio la solució més senzilla i explícita que se m’acut. A més, sempre tingueu en compte que moltes tècniques i pràctiques es poden reutilitzar des d’altres plataformes (la idea de l’atrevit NodeJS Lambda s’inspira en les anomenades ulleres atrevides del món Java).

Si us ha agradat aquest tema, llegiu el següent:

  • Heu d’aprendre a construir la millor arquitectura sense servidor
  • Com construir una canonada CI / CD sense servidor gratuïta: 3 exemples senzills
  • Fàcil replicació de DynamoDB entre regions
  • Com es crea una aplicació multi-regional (i paga zero)
  • Feu que l'aplicació web Java no sigui servidor

Els comentaris, els m'agrada i els recursos compartits són molt apreciats. De baix a dalt!