Biarkan LoopBack Melakukannya: Panduan Kerangka Node API yang Anda Impikan
Diterbitkan: 2022-03-11Tidak 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:
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:
| 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
.
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.

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.
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:
- initial - Titik pertama di mana middleware dapat berjalan.
- session - Siapkan objek sesi.
- auth - Menangani otentikasi dan otorisasi.
- parse - Mengurai badan permintaan.
- 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.
- file - Sajikan aset statis (permintaan mengenai sistem file di sini).
- final - Menangani kesalahan dan permintaan untuk URL yang tidak dikenal.
Setiap fase memiliki tiga subfase. Misalnya, subfase dari fase awal adalah:
- awal: sebelum
- awal
- 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.
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.
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!