Loopbackjs strong循环/环回-根据路由值更改连接字符串

Loopbackjs strong循环/环回-根据路由值更改连接字符串,loopbackjs,strongloop,Loopbackjs,Strongloop,我的应用程序的用户分布在不同的地理位置,数据存储在不同的区域。每个地区都有自己的数据中心和数据库服务器 我希望包含一个路由值,以指示用户希望访问和连接到的区域,如下所示: /api/地区/1/地点/ /api/地区/2/地点/ /api/地区/3/地点/ 根据传入的区域,我想更改正在使用的连接字符串。我假设这可以在中间件链的某个地方执行,但不知道在哪里/如何执行。感谢您的帮助 什么是不应该做的 环回提供了一个方法MyModel.attachTo(似乎没有文档记录,但提供了对它的引用) 但由于它是

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

我希望包含一个路由值,以指示用户希望访问和连接到的区域,如下所示:

/api/地区/1/地点/

/api/地区/2/地点/

/api/地区/3/地点/

根据传入的区域,我想更改正在使用的连接字符串。我假设这可以在中间件链的某个地方执行,但不知道在哪里/如何执行。感谢您的帮助

什么是不应该做的 环回提供了一个方法
MyModel.attachTo
(似乎没有文档记录,但提供了对它的引用)

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

因此,为了在每个请求的基础上工作,您必须在调用datasource方法之前切换DB,以确保其间没有异步启动。我认为这是不可能的

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

糟糕,不要在下面说。仅供参考

但是,当API在短时间内收到多个请求时,很可能会遇到并发问题

(另一种方式是,服务器不再是真正的无状态,执行将不仅依赖于输入,还依赖于共享状态)

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

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

可能的选择1 构建一个外部重新路由服务器,将请求从API服务器重新路由到相应的区域数据库

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

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

可能的选择2 创建一个自定义环回连接器,它将充当MySQL查询的路由器。根据查询中传递的区域值,将查询重新路由到相应的数据库

选择3 使用更分布式的体系结构。 编写特定于区域的服务器以持久化特定于区域的数据。 例如,运行3个不同的服务器,每个服务器针对一个区域进行配置。 +1个用于路由的公共服务器

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

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);
  });
});

通过
连接字符串
您的意思是
更改将持久化请求的数据源
,此选项可能是最简单的

?比如,如果用户确实
POST-api/region/1/locations/
您想持久化到美国的某个数据源,并且id为2,持久化到法国的数据源?@Overdrivr是的,这正是正确的,谢谢您的回答。我已经投了赞成票,但还没有决定采取哪种方法(可能会分析所有3种选择)。在我复习完更多之前,我将保留这个问题“未回答”。再次感谢!当然,请随时通知我我对反馈感兴趣
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);
  });
});