Toolkit Node.js untuk arsitektur Microservice
Modul open source ini disponsori dan didukung oleh Voxgig. |
---|
Seneca adalah perangkat untuk menulis layanan mikro dan mengatur logika bisnis aplikasi Anda. Anda dapat membagi aplikasi menjadi "hal-hal yang terjadi", daripada berfokus pada model data atau mengelola dependensi.
Seneca menyediakan,
pencocokan pola: cara yang sangat fleksibel untuk menangani kebutuhan bisnis
kemandirian transportasi: cara pesan sampai ke server yang tepat bukanlah sesuatu yang perlu Anda khawatirkan
jatuh tempo: 8 tahun dalam produksi (sebelum kami menyebutnya layanan mikro ), tetapi pernah dihentikan secara kilat
plus: ekosistem plugin yang mendalam dan luas
buku: panduan untuk merancang arsitektur layanan mikro: taomicro
Gunakan modul ini untuk menentukan perintah yang berfungsi dengan menggunakan beberapa JSON, dan, secara opsional, mengembalikan beberapa JSON. Perintah yang akan dijalankan dipilih dengan mencocokkan pola pada input JSON. Ada serangkaian perintah bawaan dan opsional yang membantu Anda membangun Produk yang Layak Minimum: penyimpanan data, manajemen pengguna, logika terdistribusi, caching, logging, dll. Dan Anda dapat menentukan produk Anda sendiri dengan memecahnya menjadi serangkaian perintah - " hal yang terjadi". Cukup banyak.
Jika Anda menggunakan modul ini dan memerlukan bantuan, Anda dapat:
Jika Anda baru mengenal Seneca secara umum, silakan lihat senecajs.org. Kami memiliki segalanya mulai dari tutorial hingga contoh aplikasi untuk membantu Anda memulai dan menjalankannya dengan cepat.
Sumber Seneca dapat dibaca secara beranotasi dengan menjalankan npm run annotate
. Versi beranotasi dari setiap file akan dibuat di ./docs/
.
Untuk menginstal melalui npm,
npm install seneca
'use strict'
var Seneca = require ( 'seneca' )
// Functionality in seneca is composed into simple
// plugins that can be loaded into seneca instances.
function rejector ( ) {
this . add ( 'cmd:run' , ( msg , done ) => {
return done ( null , { tag : 'rejector' } )
} )
}
function approver ( ) {
this . add ( 'cmd:run' , ( msg , done ) => {
return done ( null , { tag : 'approver' } )
} )
}
function local ( ) {
this . add ( 'cmd:run' , function ( msg , done ) {
this . prior ( msg , ( err , reply ) => {
return done ( null , { tag : reply ? reply . tag : 'local' } )
} )
} )
}
// Services can listen for messages using a variety of
// transports. In process and http are included by default.
Seneca ( )
. use ( approver )
. listen ( { type : 'http' , port : '8260' , pin : 'cmd:*' } )
Seneca ( )
. use ( rejector )
. listen ( 8270 )
// Load order is important, messages can be routed
// to other services or handled locally. Pins are
// basically filters over messages
function handler ( err , reply ) {
console . log ( err , reply )
}
Seneca ( )
. use ( local )
. act ( 'cmd:run' , handler )
Seneca ( )
. client ( { port : 8270 , pin : 'cmd:run' } )
. client ( { port : 8260 , pin : 'cmd:run' } )
. use ( local )
. act ( 'cmd:run' , handler )
Seneca ( )
. client ( { port : 8260 , pin : 'cmd:run' } )
. client ( { port : 8270 , pin : 'cmd:run' } )
. use ( local )
. act ( 'cmd:run' , handler )
// Output
// null { tag: 'local' }
// null { tag: 'approver' }
// null { tag: 'rejector' }
Untuk berjalan normal, katakanlah dalam sebuah wadah, gunakan
$ node microservice.js
(di mana microservice.js
adalah file skrip yang menggunakan Seneca). Log dikeluarkan dalam format JSON sehingga Anda dapat mengirimkannya ke layanan logging.
Untuk menjalankan dalam mode pengujian, dengan log debug lengkap yang dapat dibaca manusia, gunakan:
$ node microservice.js --seneca.test
Jadi itu tidak masalah,
Selama beberapa perintah dapat menangani dokumen JSON tertentu, Anda baik-baik saja.
Berikut ini contohnya:
var seneca = require ( 'seneca' ) ( )
seneca . add ( { cmd : 'salestax' } , function ( msg , done ) {
var rate = 0.23
var total = msg . net * ( 1 + rate )
done ( null , { total : total } )
} )
seneca . act ( { cmd : 'salestax' , net : 100 } , function ( err , result ) {
console . log ( result . total )
} )
Dalam kode ini, setiap kali Seneca melihat polanya {cmd:'salestax'}
, ia menjalankan fungsi yang terkait dengan pola ini, yaitu menghitung pajak penjualan. Tidak ada yang istimewa tentang properti cmd
. Ini hanyalah properti yang ingin kita cocokkan polanya. Anda bisa mencari foo
untuk semua urusan Seneca! Ya!
Metode seneca.add
menambahkan pola baru, dan berfungsi untuk mengeksekusi setiap kali pola itu terjadi.
Metode seneca.act
menerima sebuah objek, dan menjalankan perintah, jika ada, yang cocok.
Dari mana tarif pajak penjualan berasal? Mari kita coba lagi:
seneca . add ( { cmd : 'config' } , function ( msg , done ) {
var config = { rate : 0.23 }
var value = config [ msg . prop ]
done ( null , { value : value } )
} )
seneca . add ( { cmd : 'salestax' } , function ( msg , done ) {
seneca . act ( { cmd : 'config' , prop : 'rate' } , function ( err , result ) {
var rate = parseFloat ( result . value )
var total = msg . net * ( 1 + rate )
done ( null , { total : total } )
} )
} )
seneca . act ( { cmd : 'salestax' , net : 100 } , function ( err , result ) {
console . log ( result . total )
} )
Perintah config
memberi Anda konfigurasi Anda. Ini keren karena tidak masalah dari mana ia mendapatkan konfigurasinya - hard-code, sistem file, database, layanan jaringan, apa pun. Apakah Anda harus mendefinisikan API abstraksi agar ini berfungsi? Tidak.
Ada sedikit tapi terlalu banyak verbositas di sini, bukan begitu? Mari kita perbaiki:
seneca . act ( 'cmd:salestax,net:100' , function ( err , result ) {
console . log ( result . total )
} )
Daripada menyediakan objek, Anda bisa memberikan string menggunakan bentuk singkatan JSON. Faktanya, Anda dapat menyediakan keduanya:
seneca . act ( 'cmd:salestax' , { net : 100 } , function ( err , result ) {
console . log ( result . total )
} )
Ini adalah cara yang sangat mudah untuk menggabungkan pola dan data parameter .
Cara membangun sistem Node.js adalah dengan membangun banyak proses kecil. Inilah pembicaraan bagus yang menjelaskan mengapa Anda harus melakukan ini: Anarki Programmer.
Seneca membuat ini sangat mudah. Mari kita masukkan konfigurasi pada jaringan ke dalam prosesnya sendiri:
seneca . add ( { cmd : 'config' } , function ( msg , done ) {
var config = { rate : 0.23 }
var value = config [ msg . prop ]
done ( null , { value : value } )
} )
seneca . listen ( )
Metode listen
memulai server web yang mendengarkan pesan JSON. Ketika ini tiba, mereka diserahkan ke instansi Seneca setempat, dan dieksekusi sebagai tindakan seperti biasa. Hasilnya kemudian dikembalikan ke klien sebagai respons terhadap permintaan HTTP. Seneca juga dapat mendengarkan tindakan melalui bus pesan.
Penerapan kode konfigurasi Anda tetap sama .
Kode klien terlihat seperti ini:
seneca . add ( { cmd : 'salestax' } , function ( msg , done ) {
seneca . act ( { cmd : 'config' , prop : 'rate' } , function ( err , result ) {
var rate = parseFloat ( result . value )
var total = msg . net * ( 1 + rate )
done ( null , { total : total } )
} )
} )
seneca . client ( )
seneca . act ( 'cmd:salestax,net:100' , function ( err , result ) {
console . log ( result . total )
} )
Di sisi klien, memanggil seneca.client()
berarti Seneca akan mengirimkan tindakan apa pun yang tidak dapat dicocokkan secara lokal melalui jaringan. Dalam hal ini, server konfigurasi akan mencocokkan pola cmd:config
dan mengembalikan data konfigurasi.
Sekali lagi, perhatikan bahwa kode pajak penjualan Anda tidak berubah . Tidak perlu mengetahui dari mana konfigurasi tersebut berasal, siapa yang menyediakannya, atau bagaimana caranya.
Anda dapat melakukan ini dengan setiap perintah.
Hal tentang persyaratan bisnis adalah bahwa mereka tidak menghormati akal sehat, logika, atau struktur yang teratur. Dunia nyata berantakan.
Dalam contoh kita, katakanlah beberapa negara mempunyai tarif pajak penjualan tunggal, dan negara lain mempunyai tarif variabel, yang bergantung pada lokalitas, atau kategori produk.
Ini kodenya. Kami akan merobek kode konfigurasi untuk contoh ini.
// fixed rate
seneca . add ( { cmd : 'salestax' } , function ( msg , done ) {
var rate = 0.23
var total = msg . net * ( 1 + rate )
done ( null , { total : total } )
} )
// local rates
seneca . add ( { cmd : 'salestax' , country : 'US' } , function ( msg , done ) {
var state = {
'NY' : 0.04 ,
'CA' : 0.0625
// ...
}
var rate = state [ msg . state ]
var total = msg . net * ( 1 + rate )
done ( null , { total : total } )
} )
// categories
seneca . add ( { cmd : 'salestax' , country : 'IE' } , function ( msg , done ) {
var category = {
'top' : 0.23 ,
'reduced' : 0.135
// ...
}
var rate = category [ msg . category ]
var total = msg . net * ( 1 + rate )
done ( null , { total : total } )
} )
seneca . act ( 'cmd:salestax,net:100,country:DE' , function ( err , result ) {
console . log ( 'DE: ' + result . total )
} )
seneca . act ( 'cmd:salestax,net:100,country:US,state:NY' , function ( err , result ) {
console . log ( 'US,NY: ' + result . total )
} )
seneca . act ( 'cmd:salestax,net:100,country:IE,category:reduced' , function ( err , result ) {
console . log ( 'IE: ' + result . total )
} )
Dalam hal ini, Anda memberikan implementasi berbeda untuk pola berbeda. Ini memungkinkan Anda mengisolasi kompleksitas ke dalam tempat yang terdefinisi dengan baik. Ini juga berarti Anda dapat menangani kasus-kasus khusus dengan sangat mudah.
Organisasi Senecajs mendorong partisipasi. Jika Anda merasa dapat membantu dengan cara apa pun, baik itu dengan pelaporan bug, dokumentasi, contoh, pengujian tambahan, atau fitur baru, jangan ragu untuk membuat masalah, atau lebih baik lagi, kirimkan Permintaan Tarik. Untuk informasi lebih lanjut tentang kontribusi silakan lihat panduan Berkontribusi kami.
Untuk menjalankan pengujian secara lokal,
npm run test
Untuk mendapatkan laporan cakupan,
npm run coverage; open docs/coverage.html
Hak Cipta (c) 2010-2018 Richard Rodger dan kontributor lainnya; Berlisensi di bawah MIT .