用於微服務架構的 Node.js 工具包
此開源模組由 Voxgig 贊助和支援。 |
---|
Seneca 是一個用於編寫微服務和組織應用程式業務邏輯的工具包。您可以將應用程式分解為“發生的事情”,而不是專注於資料模型或管理依賴項。
塞內卡提供,
模式匹配:一種處理業務需求的極其靈活的方式
傳輸獨立性:訊息如何到達正確的伺服器不是您應該擔心的事情
成熟度:生產了8年(之前我們稱之為微服務),但曾經被閃電淘汰
加:深入而廣泛的插件生態系統
書籍:微服務架構設計指南:taomicro
使用此模組來定義透過接收一些 JSON 並傳回一些 JSON 來運作的命令。透過對輸入 JSON 進行模式比對來選擇要執行的命令。有內建和可選的命令集可以幫助您建立最小可行產品:資料儲存、用戶管理、分散式邏輯、快取、日誌記錄等。發生的事情」。差不多就這樣了。
如果您正在使用此模組並需要協助,您可以:
如果您對 Seneca 不太熟悉,請訪問 senecajs.org。我們擁有從教程到範例應用程式的所有內容,可幫助您快速啟動並運行。
可以透過執行npm run annotate
以註解的方式閱讀 Seneca 的原始程式碼。每個文件的註釋版本將在./docs/
中產生。
要透過 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' }
要正常運行,例如在容器中,請使用
$ node microservice.js
(其中microservice.js
是使用 Seneca 的腳本檔案)。日誌以 JSON 格式輸出,因此您可以將它們傳送至日誌記錄服務。
要在測試模式下運行並具有人類可讀的完整調試日誌,請使用:
$ node microservice.js --seneca.test
這樣就無所謂了
只要某個指令可以處理給定的 JSON 文檔,就可以了。
這是一個例子:
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 )
} )
在此程式碼中,每當 seneca 看到模式{cmd:'salestax'}
時,它就會執行與此模式關聯的函數,該函數計算銷售稅。屬性cmd
沒有什麼特別的。它只是我們想要模式匹配的屬性。您可以尋找foo
來滿足所有塞內卡的關心!啊!
seneca.add
方法新增一個新模式,以及每當該模式發生時執行的函數。
seneca.act
方法接受一個對象,並執行匹配的命令(如果有)。
銷售稅率從何而來?讓我們再試一次:
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 )
} )
config
命令為您提供設定。這很酷,因為它從哪裡獲取配置並不重要——硬編碼、檔案系統、資料庫、網路服務等等。您是否必須定義一個抽象 API 才能完成這項工作?沒有。
這裡有點冗長,但你不覺得嗎?讓我們解決這個問題:
seneca . act ( 'cmd:salestax,net:100' , function ( err , result ) {
console . log ( result . total )
} )
您可以使用 JSON 縮寫形式提供字串,而不是提供物件。事實上,您可以同時提供:
seneca . act ( 'cmd:salestax' , { net : 100 } , function ( err , result ) {
console . log ( result . total )
} )
這是組合模式和參數資料的一種非常方便的方法。
建構 Node.js 系統的方法是建立許多小進程。這是一個很好的演講,解釋了為什麼你應該這樣做:程式設計師無政府狀態。
塞內卡讓這一切變得非常簡單。讓我們將網路上的配置放入自己的進程中:
seneca . add ( { cmd : 'config' } , function ( msg , done ) {
var config = { rate : 0.23 }
var value = config [ msg . prop ]
done ( null , { value : value } )
} )
seneca . listen ( )
listen
方法啟動一個監聽 JSON 訊息的 Web 伺服器。當這些到達時,它們被提交到本地 Seneca 實例,並以正常方式作為操作執行。然後結果作為 HTTP 請求的回應傳回給客戶端。 Seneca 也可以透過訊息總線監聽操作。
您對配置代碼的實作保持不變。
客戶端程式碼如下所示:
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 )
} )
在客戶端,呼叫seneca.client()
意味著 Seneca 將透過網路發送任何它無法在本地匹配的操作。在這種情況下,配置伺服器將匹配cmd:config
模式並傳回配置資料。
再次請注意,您的銷售稅代碼不會變更。它不需要知道配置來自哪裡、由誰提供或如何提供。
您可以使用每個命令來執行此操作。
業務需求的問題在於它們不尊重常識、邏輯或有序結構。現實世界是混亂的。
在我們的範例中,假設某些國家/地區採用單一銷售稅率,而其他國家採用可變稅率,這取決於地點或產品類別。
這是代碼。我們將刪除此範例的配置程式碼。
// 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 )
} )
在這種情況下,您可以為不同的模式提供不同的實作。這使您可以將複雜性隔離到定義明確的位置。這也意味著您可以非常輕鬆地處理特殊情況。
Senecajs 組織鼓勵參與。如果您覺得自己可以以任何方式提供協助,無論是錯誤報告、文件、範例、額外測試還是新功能,請隨意建立問題,或者更好的是提交 Pull 請求。有關貢獻的更多信息,請參閱我們的貢獻指南。
要在本地運行測試,
npm run test
若要取得覆蓋率報告,
npm run coverage; open docs/coverage.html
版權所有 (c) 2010-2018 Richard Rodger 和其他貢獻者;獲得麻省理工學院許可。