Cara Membuat Sebarang Aplikasi NodeJS Tanpa Server

Saya harap anda suka Serverless seperti yang saya lakukan kerana ini adalah satu lagi jawatan pada topik itu.

Sekarang, jika kita bercakap tentang API tanpa henti tanpa pelayan, persediaan anda agak jelas pada AWS: Lambda + API Gateway.

Tetapi bagaimana pula dengan perkhidmatan lain (mikro) yang mungkin ada di belakang anda? Anda tahu, bukan idea terbaik untuk memasukkan semua kod aplikasi anda ke fungsi AWS Lambda monolitik tunggal.

Cabaran

Kami mahu dengan mudah menggunakan modul aplikasi sebagai microservices tanpa pelayan, yang juga perlu berkomunikasi antara satu sama lain. Sebaiknya, komunikasi di antara perkhidmatan harus dikawal oleh beberapa jenis ACL.

Percubaan 1. Gateway API

Ini adalah pemikiran pertama yang saya ada semasa saya cuba menyelesaikan masalah: hanya dedahkan semua mikroservices melalui API Gateway. Masalahnya ialah ... API yang dicipta adalah awam.

Mengapa masalah ini? Contohnya, kami tidak mahu mempunyai perkhidmatan pengebilan yang akan didedahkan kepada seluruh dunia, walaupun akses itu terhad menggunakan beberapa jenis kebenaran.

Nah, anda boleh membuat API swasta, tetapi dasar keselamatan cukup terhad:

Anda boleh menggunakan dasar sumber Gateway API untuk membolehkan API anda diterapkan dengan selamat oleh:
* pengguna dari akaun AWS yang ditentukan
* Rangkaian alamat IP sumber yang ditentukan atau blok CIDR
* awan peribadi maya yang dinyatakan (VPC) atau titik akhir VPC (dalam mana-mana akaun)

Hal ini membuat masalah untuk mengawal komunikasi antara perkhidmatan tersebut. Satu-satunya cara untuk melakukannya di sini adalah dengan meletakkan perkhidmatan ke VPC berasingan, terlalu banyak kerja.

Percubaan 2. Lambda

Mengapa kita tidak meletakkan setiap microservice ke AWS Lambda yang berasingan? Adakah ini akan menyelesaikan masalah ini?

Ya, sebenarnya ia akan menjadi mikroservice tanpa pelayan, dan anda akan dapat menggunakan dasar IAM untuk menyesuaikan akses antara perkhidmatan, tetapi ... Ini bukan "mudah".

Saya tahu ini agak normal pada masa kini untuk mempunyai fungsi kecil sebagai unit penyebaran anda. Dan dalam kes apabila perkhidmatan anda mempunyai lebih dari 1 titik / fungsi / fungsi akhir, ia dianggap ok untuk menggunakannya sebagai Lambdas yang banyak.

Saya faham kelebihannya, tetapi anda mengorbankan kemudahan penyelenggaraan dan pembangunan. Juga, saya sangat tidak suka idea mempunyai perkhidmatan yang digunakan sebagai satu set fungsi Lambda. Bayangkan, beberapa fungsi berasingan yang berkaitan dengan pengebilan? Ia bukan konteks lagi. Walaupun terdapat kes-kes di mana butiran tersebut mungkin berguna, tetapi ia adalah kes yang jarang berlaku.

Percubaan 3. Fat Lambda

Bolehkah kita sebenarnya menggunakan set endpoints sebagai Lambda tunggal (tanpa menggunakan API Gateway, tentu saja)?

Sekiranya kita boleh melakukan ini, kita akan mendapat semua faedah pilihan sebelumnya, tetapi kita juga akan dapat memilih granularity unit penempatan kita.

Cara yang saya mahukan adalah berikut: setiap perkhidmatan deployable harus menjadi objek JS lama biasa dengan kaedah. Ini agak remeh untuk dicapai dengan menambahkan beberapa kod gam antara objek dan AWS Lambda.

Inilah pelaksanaan saya: aws-rpc. Modul nodej ini mendedahkan fungsi lambdaHandler, di mana anda hanya lulus objek, dan secara automatiknya didedahkan kepada sesiapa sahaja yang dapat mengakses Lambda:

import {lambdaHandler} daripada 'aws-rpc';
import {TestServiceImpl} dari './TestServiceImpl';
// Ini adalah unit penyebaran anda
/ // inilah yang anda nyatakan sebagai fungsi pengendali Lambda
export const handler = lambdaHandler (new TestServiceImpl ());

Sekarang, anda hanya boleh menggunakan "pengendali" sebagai AWS Lambda. Inilah cara anda menggunakan kaedahnya:

import {TestService} dari './TestService';
const client = menunggu createClient  ("LambdaName", "test");
console.log (tunggu client.test ());

Harap maklum, agar dapat menghasilkan kaedah untuk objek rintisan klien, anda perlu lulus semua nama kaedah untuk membuatClient, seperti yang kita lakukan dalam contoh.

Ini diperlukan kerana JS tidak mempunyai sebarang maklumat runtime mengenai interface TypeScript. Saya boleh melaksanakannya dengan menggunakan kelas abstrak, tetapi saya tidak menyukainya ¯ \ _ (ツ) _ / ¯.

Bonus! Anda boleh menjalankannya secara tempatan!

Saya percaya bahawa sangat penting untuk memiliki persekitaran pembangunan tempatan anda dengan selesa. Inilah sebabnya saya juga menambah keupayaan untuk menjalankan perkhidmatan dan pelanggan tempatan tanpa menggunakan apa-apa ke AWS (lihat fungsi runService dan createClient). Sebagai contoh, lihat repositori di GitHub.

Ringkasan

Ini sangat mudah untuk tersesat dalam perkhidmatan yang menawarkan pembekal awan, dan overengineer infrastruktur anda.

Saya sentiasa memilih penyelesaian yang paling mudah dan jelas yang boleh saya fikirkan. Juga, sentiasa ingat bahawa banyak teknik dan amalan boleh digunakan semula dari platform lain (idea lemak NodeJS Lambda diilhamkan oleh botol yang dipanggil lemak dari dunia Jawa).

Sekiranya anda suka topik ini, lihat juga perkara berikut:

  • Anda Perlu Belajar Bagaimana Membuat Senibina Tanpa Pelayan Terbaik
  • Bagaimana Membuat CI / CD Pipeline Tanpa Servi percuma: 3 Contoh Mudah
  • Bagaimana Mudah Replikasi DynamoDB merentas Kawasan
  • Bagaimana Membuat Permohonan Multiregional (dan Pay Zero)
  • Buat Apa-apa Aplikasi Web Java Serverless

Komen, suka, dan saham sangat dihargai. Cheers!