Node.js微服务 4 :编写你的第一个Node.js微服务

   构建一个基于微服务的电子商务软件

4.1 微电子商务概览

   使用流行的JS框架创建一个集合所有其他微服务的微服务,并为单页面应用提供API。

   谈论4个微服务:

  1. 商品管理服务:
  2. 订单管理服务:
  3. 邮件服务:
  4. UI:

    商品管理服务:功能

  • 获取数据库中所有商品信息。这在实际生产环境中或许不是一个好方法(因为一般在生产系统中可能会需要分页),但是在我们的例子中是可行的。
  • 根据指定分类获取商品信息列表。与前一个功能类似,在生产系统中需要对结果进行分页。
  • 根据指定ID获取商品信息。
  • 将商品信息添加到数据库。该功能会使用到Seneca的数据抽象能力,将微服务与实际存储系统解耦
  • 删除商品信息
  • 编辑商品信息

    字段:名字、分类、描述以及价格。构建REST API

var plugin = function(options) {
    var seneca = this;
    
    /**
     * Fetch the list of all the products.
     */
    seneca.add({area: "product", action: "fetch"}, function(args, done) {
        var products = this.make("products");
        products.list$({}, done);
    });
    
    /**
     * Fetch the list of products by category.
     */
    seneca.add({area: "product", action: "fetch", criteria: "byCategory"}, function(args, done) {
        var products = this.make("products");
        products.list$({category: args.category}, done);
    });
    
    /**
     * Fetch a product by id.
     */
    seneca.add({area: "product", action: "fetch", criteria: "byId"}, function(args, done) {
        var product = this.make("products");
        product.load$(args.id, done);
    });
    
    /**
     * Adds a product.
     */
    seneca.add({area: "product", action: "add"}, function(args, done) {
        var products = this.make("products");
        products.category = args.category;
        products.name = args.name;
        products.description = args.description;
        products.category = args.category;
        products.price = args.price
        products.save$(function(err, product) {
            done(err, products.data$(false));
        });
    });
    
    /**
     * Removes a product by id.
     */
    seneca.add({area: "product", action: "remove"}, function(args, done) {
        var product = this.make("products");
        product.remove$(args.id, function(err) {
            done(err, null);
        });
    });
    
    /**
     * Edits a product fetching it by id first.
     */
    seneca.add({area: "product", action: "edit"}, function(args, done) {
        seneca.act({area: "product", action: "fetch", criteria: "byId", id: args.id}, function(err, result) {
            result.data$(
                    {
                        name: args.name, 
                        category: args.category, 
                        description: args.description,
                        price: args.price                        
                      }
            );
            result.save$(function(err, product){
                done(err, product.data$(false));
            });
        });
    });
}
module.exports = plugin;



var seneca = require("seneca")();
seneca.use(plugin);
seneca.use("mongo-store", {
    name: "seneca",
    host: "127.0.0.1",
    port: "27017"
});

seneca.ready(function(err){
    
    seneca.act('role:web',{use:{
      prefix: '/products',
      pin: {area:'product',action:'*'},
      map:{
        fetch: {GET:true},          
        edit: {GET:false,POST:true},
        delete: {GET: false, DELETE: true}
      }
    }});

    var express = require('express');
    var app = express();

    app.use(require("body-parser").json());
    
    // This is how you integrate Seneca with Express
    app.use( seneca.export('web') );

    app.listen(3000);

});

3.2 邮件服务:一个常见的问题

    每个公司都需要邮件服务,通过邮件给客户发送通知、账单以及注册邮件。常见问题:邮件投递失败、邮件重复发送、邮件投递错误等。简单但复杂。

    特点:只处理一个功能点、处理得很好、持有自己的专有数据。

    如何发送

    接口定义:使用了Mandrill,它支持企业级邮件发送、追溯已发送邮件和创建可在线编辑的邮件模板。

    集成Mandrill:调用Mandrill服务接口。

3.3 订单管理服务

   主要负责处理用户通过UI填写的订单。

var senecaEmailer = require("seneca")().client({host: "182.168.0.2", port: 8080});

var plugin = function(options) {
    var seneca = this;
    
    seneca.add({area: "orders", action: "fetch"}, function(args, done) {
        var orders = this.make("orders");
        orders.list$({id: args.id}, done);
    });
    
    seneca.add({area: "orders", action: "delete"}, function(args, done) {
        var orders = this.make("orders");
        orders.remove$({id: args.id}, function(err) {
                done(err, null);
        });
    });
    
    seneca.add({area: "orders", action: "create"}, function(args, done) {
        var products = args.products;
        var total = 0.0;
        products.forEach(function(product){
            total += product.price;
        });
        var orders = this.make("orders");
        orders.total = total;
        orders.customer_email = args.email;
        orders.customer_name = args.name;
        orders.save$(function(err, order) {
            var pattern = {
                area: "email", 
                action: "send", 
                template: "new_order", 
                to: args.email,
                toName: args.name,
                vars: {
                    // ... vars for rendering the template ...
                }
            }
            senecaEmailer.act(pattern, done);
        });
    });
}
module.exports = plugin;

3.4 服务降级--当出现非灾难性故障时

   邮件服务发送部分邮件失败,甚至客户根本收不到邮件,这都不影响订单处理流程。我们将这种情况称为,性能降级或服务降级。系统的响应速度可能降低,但是部分功能仍然可以使用。

   断路器:可以防止请求发送到不稳定的服务器上,避免应用失常的情况发生。


3.5 Seneca 

   追求简洁性,插件化

   还有一个优点就是可配置:使用RabbitMQ进行消息传递的插件

   https://github.com/senecajs/seneca-rabbitmq-transport

   Promise:保证某个特定事件会发生。

   调试: node-inspector


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值