Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8916

メッセージベースのMicroServiceをNode.js上で簡単につくれるSenecaを試してみた

$
0
0

背景

関わっているプロジェクトで触る機会があったので備忘録的にメモ

Senecaとは

Node.js環境でメッセージベースのMicrorServiceを簡単に構築出来るパッケージ。メッセージはJSON形式です。

Senecaの3つの重要な機能

  • Pattern matching: Instead of fragile service discovery, you just let the world know what sort of messages you care about.
  • Transport independence: You can send messages between services in many ways, all hidden from your business logic.
  • Componentisation: Functionality is expressed as a set of plugins which can be composed together as microservices.

パターンマッチング、独立した転送、コンポーネント化ということで、ソースコードに触れながらこれらの恩恵を感じていきます(笑)

Senecaの基本的な使い方

varseneca=require('seneca')()seneca.add('role:math,cmd:sum',(msg,reply)=>{reply(null,{answer:(msg.left+msg.right)})})seneca.act({role:'math',cmd:'sum',left:1,right:2},function(err,result){if(err)returnconsole.error(err)console.log(result)})

参考:http://senecajs.org/getting-started/

サンプルが凄くシンプルで解りやすかった。
seneca.addがアクションの登録、seneca.actがメッセージの送信。

seneca.add

seneca.add('role:math,cmd:sum',(msg,reply)=>{reply(null,{answer:(msg.left+msg.right)})})

1つ目のパラメータが処理対処とするメッセージ(JSON形式)のパターン
2つ目のパラメータが実際に処理対象のメッセージが来た時に実行するFunction(アクション)

アクションはmsgとreplyという2つのパラメータを持っていてmsgはメッセージのPlain Object、replyはコールバックでerrorとresponsdのシグネチャを持っています。

seneca.act

seneca.act({role:'math',cmd:'sum',left:1,right:2},function(err,result){if(err)returnconsole.error(err)console.log(result)})

1つ目のパラメータがメッセージ
2つ目のパラメータがコールバック

この例だとseneca.addのreply(null, {answer: (msg.left + msg.right)})で指定された情報がfunctin(errr, rersult)に入ってくる。

その他

seneca.prior

varseneca=require('seneca')()seneca.add('role:math,cmd:sum',function(msg,respond){varsum=msg.left+msg.rightrespond(null,{answer:sum})}).add('role:math,cmd:sum',function(msg,respond){// make an error if msg.left or msg.right is infinite valueif(!Number.isFinite(msg.left)||!Number.isFinite(msg.right)){returnrespond(newError("Expected left and right to be numbers."))}this.prior({role:'math',cmd:'sum',left:msg.left,right:msg.right,},function(err,result){if(err)returnrespond(err)result.info=msg.left+'+'+msg.rightrespond(null,result)})}).act('role:math,cmd:sum,left:1.5,right:2.5',console.log// prints { answer: 4, info: '1.5+2.5' })

priorを利用することで、メッセージに対するアクションの前に特定の処理を実行することができる。

1つ目のパラメータは事前処理を追加したいメッセージ
2つ目のパラメータは事前処理の内容

また、サンプルコードの中では1つ目のaddで追加したアクションに対して2つ目のaddでアクションのオーバーライドを行なっている。

seneca.use

require('seneca')().use(plugin,options)

useを利用することで、パッケージ化したロジックを利用することが出来る。

1つ目のパラメータは定義した関数名かプラグイン名
2つ目のパラメータは関数やプラグインに渡すオブジェクト

index.js
functionmath(options){this.add('role:math,cmd:sum',function(msg,respond){respond(null,{answer:msg.left+msg.right})})this.add('role:math,cmd:product',function(msg,respond){respond(null,{answer:msg.left*msg.right})})}require('seneca')().use(math).act('role:math,cmd:sum,left:1,right:2',console.log)

こちらが、関数名を指定したケース。
useで指定されるパッケージの場合はthissenecaのインスタンスにアクセス出来る。

math.js
module.exports=functionmath(options){this.add('role:math,cmd:sum',functionsum(msg,respond){respond(null,{answer:msg.left+msg.right})})this.add('role:math,cmd:product',functionproduct(msg,respond){respond(null,{answer:msg.left*msg.right})})}
index.js
// ①ファイルパスを指定するケースrequire('seneca')().use(require('./math.js')).act('role:math,cmd:sum,left:1,right:2',console.log)// ②パッケージ名を指定するケースrequire('seneca')().use('math')// finds ./math.js in local folder.act('role:math,cmd:sum,left:1,right:2',console.log)

こちらが、パッケージ名を指定したケース。

seneca.wrap

module.exports=functionmath(options){this.add('role:math,cmd:sum',functionsum(msg,respond){respond(null,{answer:msg.left+msg.right})})this.add('role:math,cmd:product',functionproduct(msg,respond){respond(null,{answer:msg.left*msg.right})})this.wrap('role:math',function(msg,respond){msg.left=Number(msg.left).valueOf()msg.right=Number(msg.right).valueOf()this.prior(msg,respond)})}

wrapを利用すると、特定のパターンにマッチしたメッセージのアクションをオーバーライドすることができる。上記ケースの場合はaddされた2つのアクションの事前処理としてmsg.left、msg.rghtを数値に変換している。

1つ目のパラメータは対象とするメッセージのパターン
2つ目のパラメータはオーバーライドする処理内容

For MicroService

math.js
module.exports=functionmath(options){this.add('role:math,cmd:sum',functionsum(msg,respond){respond(null,{answer:msg.left+msg.right})})this.add('role:math,cmd:product',functionproduct(msg,respond){respond(null,{answer:msg.left*msg.right})})this.wrap('role:math',function(msg,respond){msg.left=Number(msg.left).valueOf()msg.right=Number(msg.right).valueOf()this.prior(msg,respond)})}
service.js
require('seneca')().use('math').listen({type:'tcp',pin:'role:math'})
client.js
require('seneca')().client({type:'tcp',pin:'role:math'}).act('role:math,cmd:sum,left:1,right:2',console.log)

listenを利用することで、特定のパターンのメッセージをリッスンすることが出来る。便利!typeにはtcpやamqpなどパッケージをインストールすることで様々なタイプのメッセージを指定出来る。

clientを利用することで、特定のパターンのメッセージを指定したタイプにメッセージを発信出来る。

ここからは環境に依存するものが多いので、パラメーターの紹介は割愛。
参考:http://senecajs.org/getting-started/


Viewing all articles
Browse latest Browse all 8916

Trending Articles