Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Seneca workshop

Khánh Trần
September 26, 2016
130

Seneca workshop

A presentation about Microservice with SenecaJS

Khánh Trần

September 26, 2016
Tweet

Transcript

  1. TODAY > not today > philosophy > main features &

    foundation > demo > real showcase > Q & A
  2. WHY USE SENECA > focus on business logic first >

    easy to scale later > clear separation between infrastructure and app code
  3. SENECA PHILOSOPHY > Pattern matching: instead of fragile service discovery,

    you just let the world know what sort of message you case about. > Transport independence: you can send messages between services in many ways, all hidden from your business logic.
  4. FIRST MICROSERVICE // create new seneca instance const seneca =

    require('seneca')() // add new pattern seneca.add({role: 'math', cmd: 'sum'}, (msg, done) => { done(null, { answer: msg.left + msg.right }) }) // call action and receive the response seneca.act('role:math,cmd:sum', {left: 1, right: 4}, (err, result) => { if (err) return console.error(err) console.log(result) })
  5. ADD A NEW SERVICE seneca.add({role: 'math', cmd: 'product'}, (msg, done)

    => { done(null, { answer: msg.left * msg.right }) })
  6. ALL TOGETHER const seneca = require('seneca')() seneca.add({role: 'math', cmd: 'sum'},

    (msg, done) => { done(null, { answer: msg.left + msg.right}) }) seneca.add({role: 'math', cmd: 'product'}, (msg, done) => { done(null, { answer: msg.left * msg.right }) }) seneca.act('role:math,cmd:sum', {left: 2, right: 4}, (err, result) => { if (err) return console.error(err) console.log(result) }) seneca.act('role:math,cmd:product', {left: 2, right: 4}, (err, result) => { if (err) return console.error(err) console.log(result) })
  7. EXTEND FUNCTIONALITY seneca.add({role: 'math', cmd: 'sum', integer: true}, (msg, done)

    => { done(null, { answer: Math.floor(msg.left) + Math.floor(msg.right) }) })
  8. CODE RE-USE seneca.add({role: 'math', cmd: 'sum', integer: true}, (msg, done)

    => { this.act({ role: 'math', cmd: 'sum', left: Math.floor(msg.left), right: Math.floor(msg.right) }, done) })
  9. PATTERN QUICK RECAP > matches against top level properties >

    pattern are unique > specialised patterns win over generic pattern > competing patterns win based on value
  10. PLUGINS OF PATTERN > we can group several patterns into

    a single plugin using a namespacing convention > a plugin can be named > it's possible to pass a set of initial options to a plugin > usually a plugin is in a single Node module
  11. PLUGINS OF PATTERN function math (options) { this.add({role: 'math', cmd:

    'sum'}, (msg, done) => { done(null, { answer: msg.left + msg.right}) }) this.add({role: 'math', cmd: 'product'}, (msg, done) => { done(null, { answer: msg.left * msg.right }) }) } require('seneca')() .use(math) .act('role:math,cmd:sum,left:2,right:4', console.log)
  12. STORAGE > seneca provides a simple data abstraction layer, with

    four main operations: save, load, list, remove. > data as json > in-memory storage by default > a list of plugins for the most common databases
  13. STORAGE PATTERNS > load: role:entity,cmd:load,name: <entity> > list: role:entity,cmd:list,name: <entity>

    > save: role:entity,cmd:save,name: <entity> > remove: role:entity,cmd:remove,name: <entity>
  14. ACTIVE RECORD STYLE USING seneca.make METHOD WE CAN THEN const

    seneca = require('seneca')() const product = seneca.make() product.name = 'Apple' product.price = 1.99 // sends role:entity,cmd:save,name:product product.save$(console.log)
  15. STORAGE EXAMPLE const Promise = require('bluebird') seneca.add('role:cart,cmd:add', function (args, done)

    { const entity = this.make('cart_item') const save$ = Promise.promisify(entity.save$, {context: entity}) const user = args.user const item = args.item save$({user, item}) .then(model => done(null, {ok: true, model: _.omit(model, 'entity$')})) .catch(err => done(null, {ok: false, why: err.message})) }) seneca.add('role:cart,cmd:view', function (args, done) { const entity = this.make('cart_item') const list$ = Promise.promisify(entity.list$, {context: entity}) list$({user: args.user}) .then(items => done(null, {ok: true, items})) .catch(err => done(null, {ok: false, why: err.message})) })
  16. STORAGE PLUGINS LIST > PostgreSQL > MySQL > DynamoDB >

    Redis > Mongodb > Cassandra > SQLite > Hana > CouchDB > LevelDB
  17. SENECA-MESH - NO MORE SERVICE DISCOVERY! npm install seneca-balance-client npm

    install seneca-mesh // color-client.js var seneca = require('seneca')() // load the mesh plugin seneca.use('mesh') // send a message out into the network // the network will know where to send format:hex messages .act({format: 'hex', color: 'red'}, function (err, out) { // prints #FF0000 console.log(out.color) // disconnect from the network this.close() }) $ node color-service.js
  18. 1 1 Fuge is an execution environment for micro service

    development with Node.js Fuge.io.
  19. THANK YOU AND SEE YOU NEXT IN > seneca-mesh >

    Microservices vs. Monolithic