memperpanjang API yang ada dengan titik akhir khusus

12

Saya membuat API untuk banyak pelanggan. Titik akhir inti seperti /usersdigunakan oleh setiap pelanggan tetapi beberapa titik akhir bergantung pada kustomisasi individu. Jadi mungkin Pengguna A menginginkan titik akhir khusus /groupsdan tidak ada pelanggan lain yang memiliki fitur itu. Sama seperti sidenote , setiap pelanggan juga akan menggunakan skema basis datanya sendiri karena fitur-fitur tambahan tersebut.

Saya pribadi menggunakan NestJs (Ekspres di bawah tenda). Jadi app.modulesaat ini mendaftar semua modul inti saya (dengan titik akhir mereka sendiri dll.)

import { Module } from '@nestjs/common';

import { UsersModule } from './users/users.module'; // core module

@Module({
  imports: [UsersModule]
})
export class AppModule {}

Saya pikir masalah ini tidak terkait dengan NestJs jadi bagaimana Anda akan mengatasinya secara teori?

Saya pada dasarnya membutuhkan infrastruktur yang mampu menyediakan sistem dasar. Tidak ada titik akhir inti lagi karena setiap ekstensi unik dan beberapa /usersimplementasi dapat dimungkinkan. Ketika mengembangkan fitur baru, aplikasi inti tidak boleh disentuh. Ekstensi harus mengintegrasikan diri mereka sendiri atau harus terintegrasi pada saat startup. Sistem inti dikirimkan tanpa titik akhir tetapi akan diperluas dari file eksternal tersebut.

Beberapa ide muncul di benak saya


Pendekatan pertama:

Setiap ekstensi mewakili repositori baru. Tetapkan jalur ke folder eksternal khusus yang menampung semua proyek ekstensi itu. Direktori khusus ini akan berisi folder groupsdengangroups.module

import { Module } from '@nestjs/common';

import { GroupsController } from './groups.controller';

@Module({
  controllers: [GroupsController],
})
export class GroupsModule {}

API saya dapat mengulang melalui direktori itu dan mencoba mengimpor setiap file modul.

  • pro:

    1. Kode khusus disimpan jauh dari repositori inti
  • kontra:

    1. NestJs menggunakan Typescript jadi saya harus mengkompilasi kode terlebih dahulu. Bagaimana saya mengelola build API dan build dari aplikasi khusus? (Sistem plug and play)

    2. Ekstensi khusus sangat longgar karena hanya berisi beberapa file naskah. Karena kenyataannya mereka tidak memiliki akses ke direktori node_modules dari API, editor saya akan menunjukkan kepada saya kesalahan karena tidak dapat menyelesaikan dependensi paket eksternal.

    3. Beberapa ekstensi mungkin mengambil data dari ekstensi lain. Mungkin layanan grup perlu mengakses layanan pengguna. Segalanya mungkin menjadi rumit di sini.


Pendekatan kedua: Simpan setiap ekstensi di dalam subfolder dari folder src API. Tetapi tambahkan subfolder ini ke file .gitignore. Sekarang Anda dapat menyimpan ekstensi di dalam API.

  • pro:

    1. Editor Anda dapat menyelesaikan dependensi

    2. Sebelum menggunakan kode Anda, Anda dapat menjalankan perintah build dan akan memiliki satu distribusi

    3. Anda dapat mengakses layanan lain dengan mudah ( /groupsperlu mencari pengguna dengan id)

  • kontra:

    1. Ketika mengembangkan Anda harus menyalin file repositori Anda di dalam subfolder itu. Setelah mengubah sesuatu, Anda harus menyalin file-file ini kembali dan menimpa file repositori Anda dengan yang diperbarui.

Pendekatan ketiga:

Di dalam folder khusus eksternal, semua ekstensi sepenuhnya merupakan API mandiri. API utama Anda hanya akan menyediakan hal-hal otentikasi dan dapat bertindak sebagai proxy untuk mengarahkan permintaan yang masuk ke API target.

  • pro:

    1. Ekstensi baru dapat dikembangkan dan diuji dengan mudah
  • kontra:

    1. Penempatan akan sulit. Anda akan memiliki API utama dan n ekstensi API yang memulai proses mereka sendiri dan mendengarkan port.

    2. Sistem proxy bisa rumit. Jika klien meminta /usersproxy perlu tahu ekstensi API mana yang mendengarkan titik akhir itu, panggil API itu dan meneruskan respons itu kembali ke klien.

    3. Untuk melindungi API ekstensi (otentikasi ditangani oleh API utama), proxy harus berbagi rahasia dengan API tersebut. Jadi API ekstensi hanya akan mengirimkan permintaan yang masuk jika rahasia yang cocok itu disediakan dari proxy.


Pendekatan keempat:

Layanan Microsoft mungkin membantu. Saya mengambil panduan dari sini https://docs.nestjs.com/microservices/basics

Saya dapat memiliki layanan microser untuk manajemen pengguna, manajemen grup dll dan mengkonsumsi layanan tersebut dengan membuat api / gateway / proxy kecil yang memanggil layanan microser tersebut.

  • pro:

    1. Ekstensi baru dapat dikembangkan dan diuji dengan mudah

    2. Kekhawatiran terpisah

  • kontra:

    1. Penempatan akan sulit. Anda akan memiliki API utama dan n microservices memulai proses mereka sendiri dan mendengarkan port.

    2. Tampaknya saya harus membuat api gateway baru untuk setiap pelanggan jika saya ingin membuatnya disesuaikan. Jadi, alih-alih memperluas aplikasi, saya harus membuat API comsuming khusus setiap kali. Itu tidak akan menyelesaikan masalah.

    3. Untuk melindungi API ekstensi (otentikasi ditangani oleh API utama), proxy harus berbagi rahasia dengan API tersebut. Jadi API ekstensi hanya akan mengirimkan permintaan yang masuk jika rahasia yang cocok itu disediakan dari proxy.

hrp8sfH4xQ4
sumber
2
ini mungkin membantu github.com/nestjs/nest/issues/3277
Question3r
Terima kasih untuk tautannya. Tetapi saya tidak berpikir saya harus memiliki ekstensi khusus dalam kode saya. Saya akan memeriksa apakah microservices akan menyelesaikan masalah docs.nestjs.com/microservices/basics
hrp8sfH4xQ4
Saya pikir masalah Anda lebih terkait dengan otorisasi daripada istirahat.
adnanmuttaleb
@ adnanmuttaleb maukah Anda menjelaskan mengapa =?
hrp8sfH4xQ4

Jawaban:

6

Ada beberapa pendekatan untuk ini. Yang perlu Anda lakukan adalah mencari tahu alur kerja apa yang paling cocok untuk tim, organisasi, dan klien Anda.

Jika ini terserah saya, saya akan mempertimbangkan untuk menggunakan satu repositori per modul, dan menggunakan manajer paket seperti NPM dengan paket lingkup pribadi atau organisasi untuk menangani konfigurasi. Kemudian atur pipeline rilis build yang mendorong ke repo paket pada build baru.

Dengan cara ini yang Anda butuhkan adalah file utama, dan file manifes paket per instalasi kustom. Anda dapat secara independen mengembangkan dan menggunakan versi baru, dan Anda dapat memuat versi baru ketika Anda perlu di sisi klien.

Untuk menambah kehalusan, Anda dapat menggunakan file konfigurasi untuk memetakan modul ke rute dan menulis skrip generator rute generik untuk melakukan sebagian besar bootstrap.

Karena sebuah paket bisa apa saja, dependensi silang dalam paket akan bekerja tanpa banyak kesulitan. Anda hanya perlu disiplin ketika harus mengubah dan mengelola versi.

Baca lebih lanjut tentang paket pribadi di sini: Paket Pribadi NPM

Sekarang, registrasi NPM pribadi membutuhkan biaya, tetapi jika itu merupakan masalah, ada beberapa opsi lain juga. Silakan tinjau artikel ini untuk beberapa alternatif - baik gratis maupun berbayar.

Cara memiliki registry npm pribadi Anda

Sekarang jika Anda ingin menggulung manajer Anda sendiri, Anda bisa menulis pelacak layanan sederhana, yang mengambil file konfigurasi yang berisi informasi yang diperlukan untuk menarik kode dari repo, memuatnya, dan kemudian menyediakan semacam metode untuk mengambil sebuah contoh untuk itu.

Saya telah menulis implementasi referensi sederhana untuk sistem seperti itu:

Kerangka kerja: locator layanan locomotion

Contoh plugin memeriksa palindrom: contoh plugin penggerak

Aplikasi yang menggunakan kerangka kerja untuk mencari plugin: contoh aplikasi penggerak

Anda dapat bermain-main dengan ini dengan mendapatkannya dari npm menggunakan npm install -s locomotionAnda harus menentukan plugins.jsonfile dengan skema berikut:

{
    "path": "relative path where plugins should be stored",
    "plugins": [
        { 
           "module":"name of service", 
           "dir":"location within plugin folder",
           "source":"link to git repository"
        }
    ]
}

contoh:

{
    "path": "./plugins",
    "plugins": [
        {
            "module": "palindrome",
            "dir": "locomotion-plugin-example",
            "source": "https://github.com/drcircuit/locomotion-plugin-example.git"
        }
    ]
}

muat seperti ini: const loco = require ("locomotion");

Kemudian mengembalikan janji yang akan menyelesaikan objek pelacak layanan, yang memiliki metode pelacak untuk mendapatkan layanan Anda:

loco.then((svc) => {
    let pal = svc.locate("palindrome"); //get the palindrome service
    if (pal) {
        console.log("Is: no X in Nixon! a palindrome? ", (pal.isPalindrome("no X in Nixon!")) ? "Yes" : "no"); // test if it works :)
    }
}).catch((err) => {
    console.error(err);
});

Harap dicatat bahwa ini hanyalah implementasi referensi, dan tidak cukup kuat untuk aplikasi serius. Namun, polanya masih valid dan menunjukkan inti dari penulisan kerangka semacam ini.

Sekarang, ini perlu diperluas dengan dukungan untuk konfigurasi plugin, inisialisasi, pengecekan kesalahan, mungkin menambahkan dukungan untuk injeksi ketergantungan dan sebagainya.

Espen
sumber
Terima kasih. Dua masalah muncul, sepertinya kita mengandalkan npm lalu dan harus men-setup registry yang di-host sendiri. Yang kedua adalah npm pribadi tidak gratis lagi. Saya berharap menemukan solusi teknis dasar. Tapi +1 untuk idenya :)
hrp8sfH4xQ4
1
menambahkan implementasi referensi dari solusi dasar untuk sistem semacam ini.
Espen
3

Saya akan memilih opsi paket eksternal.

Anda dapat menyusun aplikasi untuk memiliki packagesfolder. Saya ingin agar UMD mengkompilasi paket-paket eksternal di folder itu sehingga naskah yang dikompilasi tidak akan memiliki masalah dengan paket-paket tersebut. Semua paket harus memiliki index.jsfile di folder root setiap paket.

Dan aplikasi Anda dapat menjalankan loop melalui folder paket menggunakan fsdan requiresemua paket index.jske dalam aplikasi Anda.

Kemudian lagi instalasi ketergantungan adalah sesuatu yang harus Anda tangani. Saya pikir file konfigurasi pada setiap paket bisa menyelesaikannya juga. Anda dapat memiliki npmskrip khusus di aplikasi utama untuk menginstal semua dependensi paket sebelum memulai aplikasi.

Dengan cara ini, Anda bisa menambahkan paket baru ke aplikasi Anda dengan menyalin menempelkan paket ke folder paket dan me-reboot aplikasi. File skrip kompilasi Anda tidak akan disentuh dan Anda tidak harus menggunakan npm pribadi untuk paket Anda sendiri.

Kalesh Kaladharan
sumber
terima kasih untuk balasan Anda. Saya pikir ini terdengar seperti solusi @ Espen yang sudah diposting, bukan?
hrp8sfH4xQ4
@ hrp8sfH4xQ4 Ya, untuk perpanjangan. Saya menambahkannya setelah membaca komentar Anda tentang tidak ingin menggunakan npm. Di atas adalah solusi yang dapat Anda lakukan untuk menghindari akun npm pribadi. Selain itu, saya yakin Anda tidak perlu menambahkan paket yang dibuat oleh seseorang di luar organisasi Anda. Baik?
Kalesh Kaladharan
btw. tetapi akan luar biasa untuk mendukung itu juga ... entah bagaimana ...
hrp8sfH4xQ4
Jika Anda perlu opsi untuk menambahkan paket pihak ketiga, maka npmadalah cara untuk melakukannya atau manajer paket lainnya. Dalam kasus seperti itu, solusi saya tidak akan cukup.
Kalesh Kaladharan
Jika Anda tidak keberatan, saya ingin menunggu untuk mengumpulkan sebanyak mungkin pendekatan
hrp8sfH4xQ4