Cara Membuat Aplikasi NodeJS Tanpa Server

Saya harap Anda menyukai Serverless seperti saya karena ini adalah posting lain tentang topik itu.

Sekarang, jika kita berbicara tentang API REST tanpa server yang sederhana, pengaturan Anda cukup jelas pada AWS: Lambda + API Gateway.

Tetapi bagaimana dengan layanan (mikro) lain yang mungkin dimiliki backend Anda? Anda tahu, itu bukan ide terbaik untuk menempatkan semua kode aplikasi Anda ke dalam fungsi AWS Lambda monolitik tunggal.

Tantangan

Kami ingin menerapkan modul aplikasi dengan mudah sebagai layanan server-mikro, yang juga perlu berkomunikasi satu sama lain. Lebih disukai, komunikasi antar layanan harus diatur oleh semacam ACL.

Percobaan 1. API Gateway

Ini adalah pemikiran pertama yang saya miliki ketika saya mencoba untuk memecahkan masalah: hanya mengekspos semua layanan microser melalui API Gateway. Masalahnya adalah ... API yang dibuat bersifat publik.

Mengapa ini menjadi masalah? Sebagai contoh, kami tidak ingin memiliki layanan penagihan untuk diekspos ke seluruh dunia, bahkan jika akses dibatasi menggunakan semacam otorisasi.

Ya, Anda dapat menjadikan API pribadi, tetapi kebijakan keamanannya sangat terbatas:

Anda dapat menggunakan kebijakan sumber daya API Gateway untuk memungkinkan API Anda dipanggil dengan aman oleh:
* pengguna dari akun AWS yang ditentukan
* rentang alamat IP sumber yang ditentukan atau blok CIDR
* Cloud pribadi virtual (VPC) atau titik akhir VPC tertentu (dalam akun apa pun)

Ini membuat cukup repot untuk mengontrol komunikasi antara layanan tersebut. Satu-satunya cara melakukannya di sini adalah dengan menempatkan layanan ke dalam VPC terpisah, terlalu banyak pekerjaan.

Percobaan 2. Lambda

Mengapa kami tidak hanya menempatkan setiap layanan mikro ke dalam AWS Lambda yang terpisah? Apakah ini akan menyelesaikan masalah?

Ya, sebenarnya itu adalah microservice tanpa server, dan Anda akan dapat menggunakan kebijakan IAM untuk menyetel akses di antara layanan, tapi ... Itu tidak “mudah”.

Saya tahu ini sangat normal saat ini untuk memiliki fungsi kecil sebagai unit penyebaran Anda. Dan dalam hal ketika layanan Anda memiliki lebih dari 1 titik akhir / metode / fungsi, itu dianggap ok untuk menyebarkannya sebagai beberapa Lambdas.

Saya mengerti kelebihannya, tetapi Anda mengorbankan kemudahan pemeliharaan dan pengembangan. Juga, saya benar-benar tidak menyukai gagasan memiliki layanan yang digunakan sebagai serangkaian fungsi Lambda. Bayangkan, beberapa fungsi terpisah berurusan dengan penagihan? Ini bukan konteks yang dibatasi lagi. Meskipun ada kasus-kasus di mana granularity seperti itu mungkin berguna, tetapi itu adalah kasus yang jarang terjadi.

Percobaan 3. Fat Lambda

Bisakah kita benar-benar menggunakan satu set titik akhir sebagai satu Lambda (tanpa menggunakan API Gateway, tentu saja)?

Jika kami dapat melakukan ini, kami akan mendapatkan semua manfaat dari opsi sebelumnya, tetapi kami juga dapat memilih rincian unit penempatan kami.

Cara yang saya inginkan adalah sebagai berikut: setiap layanan yang dapat digunakan harus sederhana JS objek tua dengan metode. Ini cukup sepele untuk dicapai dengan menambahkan beberapa baris kode lem antara objek Anda dan AWS Lambda.

Ini implementasi saya untuk itu: aws-rpc. Modul nodejs ini memaparkan fungsi lambdaHandler, di mana Anda baru saja melewati sebuah objek, dan secara otomatis terpapar pada siapa saja yang dapat mengakses Lambda:

impor {lambdaHandler} dari 'aws-rpc';
impor {TestServiceImpl} dari './TestServiceImpl';
// ini adalah unit penyebaran Anda
// inilah yang Anda tentukan sebagai fungsi pengendali Lambda
export const handler = lambdaHandler (TestServiceImpl () baru);

Sekarang, Anda bisa menggunakan "handler" sebagai AWS Lambda. Inilah cara Anda menjalankan metodenya:

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

Harap dicatat, bahwa untuk dapat menghasilkan metode untuk objek rintisan klien, Anda harus meneruskan semua nama metode ke createClient, seperti yang kami lakukan dalam contoh.

Ini diperlukan karena JS tidak memiliki informasi runtime apa pun tentang antarmuka TypeScript. Saya bisa mengimplementasikannya menggunakan kelas abstrak, tetapi saya tidak menyukainya ¯ \ _ (ツ) _ / ¯.

Bonus! Anda dapat menjalankan semuanya secara lokal!

Saya percaya bahwa sangat penting untuk membuat lingkungan pengembangan lokal Anda senyaman mungkin. Inilah sebabnya saya juga menambahkan kemampuan untuk menjalankan layanan dan klien secara lokal tanpa menggunakan apa pun untuk AWS (lihat fungsi runService dan createClient). Sebagai contoh, lihat repositori di GitHub.

Ringkasan

Ini sangat mudah tersesat dalam layanan yang ditawarkan penyedia cloud, dan merekayasa ulang infrastruktur Anda.

Saya selalu memilih solusi paling sederhana dan eksplisit yang dapat saya pikirkan. Juga, selalu ingat bahwa banyak teknik dan praktik dapat digunakan kembali dari platform lain (gagasan NodeJS lemak Lambda terinspirasi oleh apa yang disebut guci lemak dari dunia Jawa).

Jika Anda menyukai topik ini, periksa juga ini:

  • Anda Harus Mempelajari Cara Membuat Arsitektur Tanpa Server Terbaik
  • Cara Membuat Pipeline CI / CD Tanpa Server Gratis: 3 Contoh Mudah
  • Cara Mudah Meniru DynamoDB di seluruh Wilayah
  • Cara Membuat Aplikasi Multiregional (dan Membayar Nol)
  • Membuat Aplikasi Web Java Apa Pun Tanpa Server

Komentar, suka, dan bagikan sangat dihargai. Tepuk tangan!