Biarkan LoopBack Melakukannya: Panduan Kerangka Node API yang Anda Impikan

Diterbitkan: 2022-03-11

Tidak perlu disebutkan lagi semakin populernya Node.js untuk pengembangan aplikasi. eBay telah menjalankan layanan Node API produksi sejak 2011. PayPal secara aktif membangun kembali front-end mereka di Node.js. Situs seluler Walmart telah menjadi aplikasi Node terbesar, dari segi lalu lintas. Pada akhir pekan Thanksgiving tahun 2014, server Walmart memproses 1,5 miliar permintaan, 70 persen di antaranya dikirim melalui seluler dan didukung oleh Node.js. Di sisi pengembangan, manajer paket Node (npm) terus berkembang pesat, baru-baru ini melampaui 150.000 modul yang dihosting.

Sementara Ruby memiliki Rails dan Python memiliki Django, kerangka kerja pengembangan aplikasi yang dominan untuk Node belum ditetapkan. Tapi, ada pesaing kuat yang mendapatkan tenaga: LoopBack, kerangka kerja API open source yang dibangun oleh San Mateo, California, perusahaan StrongLoop. StrongLoop adalah kontributor penting untuk versi Node terbaru, belum lagi pengelola lama Express, salah satu kerangka kerja Node paling populer yang ada.

Mari kita lihat lebih dekat LoopBack dan kemampuannya dengan mengubah semuanya menjadi praktik dan membangun aplikasi contoh.

Apa itu LoopBack dan Bagaimana Cara Kerjanya dengan Node?

LoopBack adalah kerangka kerja untuk membuat API dan menghubungkannya dengan sumber data backend. Dibangun di atas Express, ini dapat mengambil definisi model data dan dengan mudah menghasilkan API REST ujung-ke-ujung yang berfungsi penuh yang dapat dipanggil oleh klien mana pun.

LoopBack hadir dengan klien bawaan, API Explorer . Kami akan menggunakan ini karena memudahkan untuk melihat hasil pekerjaan kami, dan agar contoh kami dapat fokus pada pembuatan API itu sendiri.

Anda tentu saja membutuhkan Node yang diinstal pada mesin Anda untuk mengikutinya. Dapatkan disini. npm hadir dengannya, sehingga Anda dapat menginstal paket yang diperlukan dengan mudah. Mari kita mulai.

Buat Kerangka

Aplikasi kami akan mengelola orang-orang yang ingin menyumbangkan hadiah, atau hal-hal yang tidak mereka butuhkan lagi, kepada seseorang yang mungkin membutuhkannya. Jadi, pengguna akan menjadi Donatur dan Penerima. Donor dapat membuat hadiah baru dan melihat daftar hadiah. Penerima dapat melihat daftar hadiah dari semua pengguna, dan dapat mengklaim hadiah yang tidak diklaim. Tentu saja, kita dapat membangun Donor dan Penerima sebagai peran terpisah pada entitas yang sama (Pengguna), tetapi mari kita coba memisahkannya sehingga kita dapat melihat bagaimana membangun hubungan di LoopBack. Nama aplikasi inovatif ini adalah Givesomebody .

Instal alat baris perintah StrongLoop melalui npm:

 $ npm install -g strongloop

Kemudian jalankan generator aplikasi LoopBack:

 $ slc loopback _-----_ | | .--------------------------. |--(o)--| | Let's create a LoopBack | `--------- | application! | ( _U`_ ) '--------------------------' /___A___\ | ~ | __'.___.'__ ` |° Y ` ? What's the name of your application? Givesomebody

Mari tambahkan model. Model pertama kami akan disebut Gift. LoopBack akan menanyakan sumber data dan kelas dasar. Karena kita belum menyiapkan sumber data, kita bisa meletakkan db (memory) . Kelas dasar adalah kelas model yang dibuat secara otomatis, dan kami ingin menggunakan PersistedModel dalam kasus ini, karena sudah berisi semua metode CRUD yang biasa untuk kami. Selanjutnya, LoopBack menanyakan apakah model harus diekspos melalui REST (ya), dan nama layanan REST. Tekan enter di sini untuk menggunakan default, yang merupakan bentuk jamak dari nama model (dalam kasus kami, gifts ).

 $ slc loopback:model ? Enter the model name: Gift ? Select the data-source to attach Gift to: (Use arrow keys) ❯ db (memory) ? Select model's base class: (Use arrow keys) Model ❯ PersistedModel ? Expose Gift via the REST API? (Y/n) Yes ? Custom plural form (used to build REST URL):

Terakhir, kami memberikan nama properti, tipe datanya, dan flag wajib/tidak wajib. Hadiah akan memiliki properti name dan description :

 Let's add some Gift properties now. Enter an empty property name when done. ? Property name: name invoke loopback:property ? Property type: (Use arrow keys) ❯ string ? Required? (y/N)Yes

Masukkan nama properti kosong untuk menunjukkan bahwa Anda telah selesai mendefinisikan properti.

Generator model akan membuat dua file yang mendefinisikan model dalam common/models aplikasi : gift.json dan gift.js . File JSON menentukan semua metadata tentang entitas: properti, relasi, validasi, peran, dan nama metode. File JavaScript digunakan untuk mendefinisikan perilaku tambahan, dan untuk menentukan pengait jarak jauh yang akan dipanggil sebelum atau setelah operasi tertentu (mis., buat, perbarui, atau hapus).

Dua entitas model lainnya akan menjadi model Donor dan Receiver kami. Kita dapat membuatnya menggunakan proses yang sama, kecuali kali ini kita menempatkan User sebagai kelas dasar. Ini akan memberi kita beberapa properti seperti username , password , email out of the box. Kita dapat menambahkan nama dan negara saja, misalnya, untuk memiliki entitas lengkap. Untuk Penerima kami ingin menambahkan alamat pengiriman juga.

Struktur Proyek

Mari kita lihat struktur proyek yang dihasilkan:

Struktur proyek

Tiga direktori utama adalah: - /server – Berisi skrip aplikasi node dan file konfigurasi. - /client – ​​Berisi .js, .html, .css, dan semua file statis lainnya. - /common – Folder ini umum untuk server dan klien. File model ada di sini.

Berikut rincian rinci dari isi setiap direktori, diambil dari dokumentasi LoopBack:

File atau direktori Keterangan Cara mengakses dalam kode
Direktori aplikasi tingkat atas
package.json Spesifikasi paket npm standar. Lihat package.json T/A
/ direktori server - File aplikasi node
server.js File program aplikasi utama. T/A
config.json Pengaturan aplikasi. Lihat config.json. app.get('setting-name')
datasources.json File konfigurasi sumber data. Lihat sumber data.json. Sebagai contoh, lihat Membuat sumber data baru . app.datasources['datasource-name']
model-config.json File konfigurasi model. Lihat model-config.json. Untuk informasi lebih lanjut, lihat Menghubungkan model ke sumber data . T/A
middleware.json File definisi middleware. Untuk informasi lebih lanjut, lihat Mendefinisikan middleware. T/A
/boot Tambahkan skrip untuk melakukan inisialisasi dan penyiapan. Lihat skrip boot. Script secara otomatis dieksekusi dalam urutan abjad.
/ direktori klien - file aplikasi klien
README.md Generator LoopBack membuat file README kosong dalam format penurunan harga. T/A
Lainnya Tambahkan file HTML, CSS, klien JavaScript Anda.
/ direktori umum - file aplikasi bersama
/models File model khusus:
  • File JSON definisi model, dengan konvensi bernama model-name .json ; misalnya customer.json .
  • Skrip model khusus menurut konvensi bernama model-name .js ; misalnya, customer.js .
Untuk informasi selengkapnya, lihat File JSON definisi model dan Menyesuaikan model.
simpul:
myModel = app.models.myModelName

Bangun Hubungan

Dalam contoh kami, kami memiliki beberapa hubungan penting untuk dimodelkan. Seorang Donor dapat menyumbangkan banyak Hadiah, yang memberi relasi Donor memiliki banyak Hadiah . Seorang Penerima juga dapat menerima banyak Hadiah, jadi kita juga memiliki relasi Penerima memiliki banyak Hadiah . Di sisi lain, Hadiah adalah milik Donor , dan juga bisa menjadi milik Penerima jika Penerima memilih untuk menerimanya. Mari kita masukkan ini ke dalam bahasa LoopBack.

 $ slc loopback:relation ? Select the model to create the relationship from: Donor ? Relation type: has many ? Choose a model to create a relationship with: Gift ? Enter the property name for the relation: gifts ? Optionally enter a custom foreign key: ? Require a through model? No

Perhatikan bahwa tidak ada model tembus; kami hanya memegang referensi ke Hadiah.

Jika kita mengulangi prosedur di atas untuk Penerima, dan menambahkan dua milik relasi ke Hadiah, kita akan menyelesaikan desain model kita di sisi belakang. LoopBack secara otomatis memperbarui file JSON untuk model untuk mengekspresikan dengan tepat apa yang baru saja kita lakukan melalui dialog sederhana berikut:

 // common/models/donor.json ... "relations": { "gifts": { "type": "hasMany", "model": "Gift", "foreignKey": "" } }, ...

Tambahkan Sumber Data

Sekarang mari kita lihat bagaimana melampirkan sumber data nyata untuk menyimpan semua data aplikasi kita. Untuk tujuan contoh ini, kita akan menggunakan MongoDB, tetapi LoopBack memiliki modul untuk terhubung dengan Oracle, MySQL, PostgreSQL, Redis dan SQL Server.

Pertama, instal konektor:

 $ npm install --save loopback-connector-mongodb

Kemudian, tambahkan sumber data ke proyek Anda:

 $ slc loopback:datasource ? Enter the data-source name: givesomebody ? Select the connector for givesomebody: MongoDB (supported by StrongLoop)

Langkah selanjutnya adalah mengonfigurasi sumber data Anda di server/datasources.json . Gunakan konfigurasi ini untuk server MongoDB lokal:

 ... "givesomebody": { "name": "givesomebody", "connector": "mongodb", "host": "localhost", "port": 27017, "database": "givesomebody", "username": "", "password": "" } ...

Terakhir, buka server/model-config.json dan ubah datasource untuk semua entitas yang ingin kita pertahankan dalam database menjadi "givesomebody" .

 { ... "User": { "dataSource": "givesomebody" }, "AccessToken": { "dataSource": "givesomebody", "public": false }, "ACL": { "dataSource": "givesomebody", "public": false }, "RoleMapping": { "dataSource": "givesomebody", "public": false }, "Role": { "dataSource": "givesomebody", "public": false }, "Gift": { "dataSource": "givesomebody", "public": true }, "Donor": { "dataSource": "givesomebody", "public": true }, "Receiver": { "dataSource": "givesomebody", "public": true } }

Menguji API REST Anda

Saatnya untuk melihat apa yang telah kita bangun sejauh ini! Kami akan menggunakan alat bawaan yang mengagumkan, API Explorer , yang dapat digunakan sebagai klien untuk layanan yang baru saja kami buat. Mari kita coba menguji panggilan REST API.

Di jendela terpisah, mulai MongoDB dengan:

 $ mongod

Jalankan aplikasi dengan:

 $ node .

Di browser Anda, buka http://localhost:3000/explorer/ . Anda dapat melihat entitas Anda dengan daftar operasi yang tersedia. Coba tambahkan satu Donor dengan panggilan POST /Donors .

Menguji API Anda 2

Menguji API Anda 3

API Explorer sangat intuitif; pilih salah satu metode yang terbuka, dan skema model yang sesuai akan ditampilkan di sudut kanan bawah. Di area teks data , dimungkinkan untuk menulis permintaan HTTP khusus. Setelah permintaan diisi, klik tombol “Cobalah”, dan respons server akan ditampilkan di bawah.

Menguji API Anda 1

Otentikasi Pengguna

Seperti disebutkan di atas, salah satu entitas yang telah dibuat sebelumnya dengan LoopBack adalah kelas Pengguna. Pengguna memiliki metode masuk dan keluar, dan dapat diikat ke entitas AccessToken yang menyimpan token pengguna tertentu. Faktanya, sistem otentikasi pengguna yang lengkap siap digunakan. Jika kami mencoba memanggil /Donors/login melalui API Explorer , berikut adalah respons yang kami dapatkan:

 { "id": "9Kvp4zc0rTrH7IMMeRGwTNc6IqNxpVfv7D17DEcHHsgcAf9Z36A3CnPpZJ1iGrMS", "ttl": 1209600, "created": "2015-05-26T01:24:41.561Z", "userId": "" }

id sebenarnya adalah nilai AccessToken, yang dihasilkan dan disimpan dalam database secara otomatis. Seperti yang Anda lihat di sini, adalah mungkin untuk mengatur token akses dan menggunakannya untuk setiap permintaan berikutnya.

Otentikasi pengguna

Metode Jarak Jauh

Metode jarak jauh adalah metode statis model, diekspos melalui titik akhir REST khusus. Metode jarak jauh dapat digunakan untuk melakukan operasi yang tidak disediakan oleh REST API model standar LoopBack.

Selain metode CRUD yang kami dapatkan di luar kotak, kami dapat menambahkan metode kustom sebanyak yang kami inginkan. Semuanya harus masuk ke file [model].js . Dalam kasus kami, mari tambahkan metode jarak jauh ke model Hadiah untuk memeriksa apakah hadiah sudah dipesan, dan satu untuk mendaftar semua hadiah yang tidak dipesan.

Pertama, mari tambahkan properti tambahan ke model yang disebut reserved . Cukup tambahkan ini ke properti di gift.json :

 ... "reserved": { "type": "boolean" } ...

Metode jarak jauh di gift.js akan terlihat seperti ini:

 module.exports = function(Gift) { // method which lists all free gifts Gift.listFree = function(cb) { Gift.find({ fields: { reserved: false } }, cb); }; // expose the above method through the REST Gift.remoteMethod('listFree', { returns: { arg: 'gifts', type: 'array' }, http: { path: '/list-free', verb: 'get' } }); // method to return if the gift is free Gift.isFree = function(id, cb) { var response; Gift.find({ fields: { id: id } }, function(err, gift) { if (err) return cb(err); if (gift.reserved) response = 'Sorry, the gift is reserved'; else response = 'Great, this gift can be yours'; }); cb(null, response); }; // expose the method through REST Gift.remoteMethod('isFree', { accepts: { arg: 'id', type: 'number' }, returns: { arg: 'response', type: 'string' }, http: { path: '/free', verb: 'post' } }); };

Jadi untuk mengetahui apakah hadiah tertentu tersedia, klien sekarang dapat mengirim permintaan POST ke /api/Gifts/free , dengan memasukkan id hadiah yang dimaksud.

Kait Jarak Jauh

Terkadang ada kebutuhan untuk mengeksekusi beberapa metode sebelum atau sesudah metode jarak jauh. Anda dapat menentukan dua jenis pengait jarak jauh:

  • beforeRemote() berjalan sebelum metode jarak jauh.
  • afterRemote() berjalan setelah metode jarak jauh.

Dalam kedua kasus, Anda memberikan dua argumen: string yang cocok dengan metode jarak jauh yang ingin Anda "kaitkan" dengan fungsi Anda, dan fungsi panggilan balik. Sebagian besar kekuatan kait jarak jauh adalah bahwa string dapat menyertakan wildcard, sehingga dipicu oleh metode pencocokan apa pun.

Dalam kasus kita, mari kita atur pengait untuk mencetak informasi ke konsol setiap kali Donor baru dibuat. Untuk mencapai ini, mari tambahkan hook "sebelum membuat" di donor.js :

 module.exports = function(Donor) { Donor.beforeRemote('create', function(context, donor, next) { console.log('Saving new donor with name: ', context.req.body.name); next(); }); };

Permintaan dipanggil dengan context yang diberikan, dan panggilan balik next() di middleware (dibahas di bawah) dipanggil setelah hook berjalan.

Kontrol Akses

Aplikasi LoopBack mengakses data melalui model, jadi mengontrol akses ke data berarti menentukan batasan pada model; yaitu, menentukan siapa atau apa yang dapat membaca dan menulis data atau mengeksekusi metode pada model. Kontrol akses LoopBack ditentukan oleh daftar kontrol akses, atau ACL.

Mari izinkan Donor dan Penerima yang tidak masuk untuk melihat hadiah, tetapi hanya Donor yang masuk untuk membuat dan menghapusnya.

 $ slc loopback:acl

Untuk memulai, mari kita tolak akses semua orang ke semua titik akhir.

 ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: All methods and properties ? Select the access type: All (match all types) ? Select the role: All users ? Select the permission to apply: Explicitly deny access

Selanjutnya, izinkan semua orang membaca dari model Hadiah:

 $ slc loopback:acl ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: All methods and properties ? Select the access type: Read ? Select the role: All users ? Select the permission to apply: Explicitly grant access

Kemudian, kami ingin mengizinkan pengguna yang diautentikasi untuk membuat Hadiah:

 $ slc loopback:acl ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: A single method ? Enter the method name: create ? Select the role: Any authenticated user ? Select the permission to apply: Explicitly grant access

Dan terakhir, izinkan pemilik hadiah untuk membuat perubahan apa pun:

 $ slc loopback:acl ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: All methods and properties ? Select the access type: Write ? Select the role: The user owning the object ? Select the permission to apply: Explicitly grant access

Sekarang ketika kami meninjau gift.json , semuanya harus di tempat:

 "acls": [ { "accessType": "*", "principalType": "ROLE", "principalId": "$everyone", "permission": "DENY" }, { "accessType": "READ", "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" }, { "accessType": "EXECUTE", "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW", "property": "create" } ],

Satu catatan penting di sini: $authenticated adalah peran yang telah ditentukan sebelumnya yang sesuai dengan semua pengguna dalam sistem (baik Donor dan Penerima), tetapi kami hanya ingin mengizinkan Donor untuk membuat Hadiah baru. Oleh karena itu, kami membutuhkan peran khusus. Karena Role adalah satu lagi entitas yang kita keluarkan dari kotak, kita dapat memanfaatkan panggilan API-nya untuk membuat peran $authenticatedDonor dalam fungsi boot, dan kemudian hanya memodifikasi pricipalId di gift.json .

Anda perlu membuat file baru, server/boot/script.js , dan menambahkan kode berikut:

 Role.create({ name: 'authenticatedDonor' }, function(err, role) { if (err) return debug(err); })

Entitas RoleMapping memetakan Peran ke Pengguna. Pastikan Peran dan Pemetaan Peran keduanya diekspos melalui REST. Di server/model-config.json , periksa apakah "public" disetel ke true untuk entitas Peran. Kemudian di donor.js , kita bisa menulis hook "sebelum membuat" yang akan memetakan userID dan roleID dalam panggilan RoleMapping POST API.

perangkat tengah

Middleware berisi fungsi yang dijalankan ketika permintaan dibuat ke titik akhir REST. Karena LoopBack didasarkan pada Express, ia menggunakan middleware Express dengan satu konsep tambahan, yang disebut "fase middleware." Fase digunakan untuk mendefinisikan dengan jelas urutan pemanggilan fungsi di middleware.

Berikut adalah daftar fase yang telah ditentukan sebelumnya, seperti yang disediakan dalam dokumen LoopBack:

  1. initial - Titik pertama di mana middleware dapat berjalan.
  2. session - Siapkan objek sesi.
  3. auth - Menangani otentikasi dan otorisasi.
  4. parse - Mengurai badan permintaan.
  5. route - Rute HTTP yang mengimplementasikan logika aplikasi Anda. Middleware yang didaftarkan melalui Express API app.use, app.route, app.get (dan kata kerja HTTP lainnya) berjalan di awal fase ini. Gunakan fase ini juga untuk sub-aplikasi seperti loopback/server/middleware/rest atau loopback-explorer.
  6. file - Sajikan aset statis (permintaan mengenai sistem file di sini).
  7. final - Menangani kesalahan dan permintaan untuk URL yang tidak dikenal.

Setiap fase memiliki tiga subfase. Misalnya, subfase dari fase awal adalah:

  1. awal: sebelum
  2. awal
  3. awal: setelah

Mari kita lihat sekilas middleware.json default kami:

 { "initial:before": { "loopback#favicon": {} }, "initial": { "compression": {}, "cors": { "params": { "origin": true, "credentials": true, "maxAge": 86400 } } }, "session": { }, "auth": { }, "parse": { }, "routes": { }, "files": { }, "final": { "loopback#urlNotFound": {} }, "final:after": { "errorhandler": {} } }

Pada fase awal, kita memanggil loopback.favicon() ( loopback#favicon adalah id middleware untuk panggilan itu). Kemudian, compression dan cors modul npm pihak ketiga dipanggil (dengan atau tanpa parameter). Pada fase terakhir, kami memiliki dua panggilan lagi. urlNotFound adalah panggilan LoopBack, dan errorhandler adalah modul pihak ketiga. Contoh ini harus menunjukkan bahwa banyak panggilan bawaan dapat digunakan seperti modul npm eksternal. Dan tentu saja, kita selalu dapat membuat middleware kita sendiri dan memanggilnya melalui file JSON ini.

loopback-boot

Sebagai penutup, sebut saja modul yang mengekspor fungsi boot() yang menginisialisasi aplikasi. Di server/server.js Anda akan menemukan potongan kode berikut, yang mem-bootstrap aplikasi:

 boot(app, __dirname, function(err) { if (err) throw err; // start the server if `$ node server.js` if (require.main === module) app.start(); });

Skrip ini akan mencari folder server/boot , dan memuat semua skrip yang ditemukan di sana dalam urutan abjad. Jadi, di server/boot , kita dapat menentukan skrip apa saja yang harus dijalankan saat start. Salah satu contohnya adalah explorer.js , yang menjalankan API Explorer , klien yang kami gunakan untuk menguji API kami.

Punya pengulangan blues? Jangan buat API Node itu dari awal lagi. Biarkan LoopBack melakukannya!
Menciak

Kesimpulan

Sebelum saya meninggalkan Anda, saya ingin menyebutkan StrongLoop Arc, UI grafis yang dapat digunakan sebagai alternatif alat baris perintah slc . Ini juga mencakup alat untuk membangun, membuat profil, dan memantau aplikasi Node. Bagi mereka yang bukan penggemar baris perintah, ini pasti patut dicoba. Namun, StrongLoop Arc akan segera dihentikan dan fungsinya sedang diintegrasikan ke dalam Toolkit Pengembang IBM API Connect.

Kesimpulan

Secara umum, LoopBack dapat menghemat banyak pekerjaan manual karena Anda mendapatkan banyak hal di luar kotak. Ini memungkinkan Anda untuk fokus pada masalah khusus aplikasi dan logika bisnis. Jika aplikasi Anda didasarkan pada operasi CRUD dan memanipulasi entitas yang telah ditentukan sebelumnya, jika Anda bosan menulis ulang infrastruktur otentikasi dan otorisasi pengguna ketika banyak pengembang telah menulisnya sebelum Anda, atau jika Anda ingin memanfaatkan semua keuntungan dari kerangka kerja web yang hebat seperti Express, lalu membangun REST API Anda dengan LoopBack dapat mewujudkan impian Anda. Ini sepotong kue!