strongloop / loopback - 根据路由值更改连接字符串

时间:2016-10-06 03:34:55

标签: loopbackjs strongloop

我的应用程序的用户在地理位置上分散,数据存储在不同的区域。每个地区都有自己的数据中心和数据库服务器。

我想包含一个路由值来指示用户想要访问和连接的区域,如下所示:

  

/ api / region / 1 / locations /

     

/ API /区域/ 2 /位置/

     

/ API /区域/ 3 /位置/

根据传入的区域,我想更改正在使用的连接字符串。我认为这可以在中间件链中的某个地方执行,但不知道在哪里/如何。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

不应该做什么

Loopback提供了一种方法MyModel.attachTo(似乎没有记录,但是对它的引用是there)。

但由于它是一个静态方法,它会影响整个模型,而不是单个实例。

因此,为了在每个请求的基础上工作,必须在调用数据源方法之前切换数据库,以确保在它们之间没有任何异步启动。我不认为这是可能的。

这是一个使用操作挂钩的示例(并在dbRegion1中定义所有数据源,包括datasources.json

  

不好,不要在下面。仅供参考

Region.observe('loaded', function filterProperties(ctx, next) {
   app.models.Region.attachTo(app.dataSources.dbRegion1);
}

但是,当您的API在短时间内收到多个请求时,您很可能面临并发问题。

(另一种看待它的方式是服务器不再是真正无状态的,执行不仅取决于输入,还取决于共享状态)。

钩子可以为请求2设置region2,而钩子之后调用的方法期望对请求1使用region1。如果钩子和钩子之间触发了异步,则会出现这种情况。实际调用数据源方法。

所以最终,我认为你不应该这样做。我只是把它放在那里,因为有些人在其他SO帖子中推荐它,但它只是糟糕。

潜在选项1

构建外部重新路由服务器,该服务器将请求从API服务器重新路由到相应的区域数据库。

使用API​​服务器中的loopback-connector-rest来使用此微服务,并将其用作所有模型的单个数据源。这提供了对数据库选择的抽象。

当然,仍然存在实现微服务的问题,但也许您可以找到一些其他ORM而不是支持数据库分片的环回,并在该微服务中使用它。

潜在选项2

创建一个自定义环回连接器,用作MySQL查询的路由器。根据查询中传递的区域值,将查询重新路由到相应的DB。

选项3

使用更分散的架构。 编写特定于区域的服务器以保留区域特定的数据。 例如,运行3个不同的服务器,每个服务器都为一个区域配置。 + 1个用于路由的公共服务器

然后为面向用户的单个REST api服务器构建路由中间件。 基本示例:

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

var ips = ['127.0.0.1', '127.0.0.2'];

app.all('/api/region/:id', function (req, res, next) {
  console.log('Reroute to region server ' + req.params.id);
  request(ips[req.params.id], function (error, response, body) {
    if (err) return next(err);
    next(null, body);
  });
});

也许这个选项最容易做到