环回:如何在代码中动态创建自定义REST端点(动态)

环回:如何在代码中动态创建自定义REST端点(动态),rest,dynamic,endpoint,loopbackjs,strongloop,Rest,Dynamic,Endpoint,Loopbackjs,Strongloop,我们正在使用环回REST框架来公开我们的数据库(和业务逻辑)。我们需要允许客户在数据库中创建自定义表(单租户和多租户),这些表可以通过REST端点访问。所有客户都需要使用相同的公共(生产)REST端点,这些端点将在多台服务器上公开。但是,自定义表和关联的REST端点需要仅对创建它们的客户进行访问。这意味着我们无法将自定义表的模型写入光盘。我们需要能够在生产REST端点的上下文中动态创建实际的REST端点 问题:我们如何在代码中动态创建自定义REST端点(动态),而不将模型写入光盘上的JSON文件

我们正在使用环回REST框架来公开我们的数据库(和业务逻辑)。我们需要允许客户在数据库中创建自定义表(单租户和多租户),这些表可以通过REST端点访问。所有客户都需要使用相同的公共(生产)REST端点,这些端点将在多台服务器上公开。但是,自定义表和关联的REST端点需要仅对创建它们的客户进行访问。这意味着我们无法将自定义表的模型写入光盘。我们需要能够在生产REST端点的上下文中动态创建实际的REST端点

问题:我们如何在代码中动态创建自定义REST端点(动态),而不将模型写入光盘上的JSON文件?

您可以在模型的JS文件中创建一个自定义REST端点,这会在“运行时”添加API挂钩,尽管它处于启动状态。也就是说,我认为您可以随时使用相同的函数来添加端点,而不仅仅是在启动时(尽管我从未尝试过):

内部
/common/models/MyModel.js

module.exports = function(MyModel){

  // This is the endpoint for creating endpoints...
  MyModel.addEndpoint = function(name, method, cb) {
    // audit name and method...

    MyModel[name] = function(options, newCb) {
      // do whatever this endpoint should do...
      newCb(null, 'New endpoint success!');
    };

    MyModel.remoteMethod(
      name, 
      {
        accepts: [{arg: 'options', type: 'object'}], // or whatever you need...
        returns: {arg: 'message', type: 'string'}, // whatever it returns...
        http: {verb: method}
      }
    );

    cb(null, 'Success creating new endpoint!');
  };

  MyModel.remoteMethod(
    'addEndpoint', 
    {
      accepts: [
        {arg: 'name', type: 'string', http: {source: 'body'}},
        {arg: 'method', type: 'string', http: {source: 'body'}}
      ],
      returns: {arg: 'message', type: 'string'},
      http: {verb: 'post'}
    }
  );
};

我在环回中一直面临类似的问题。 我想出的解决办法是:

  • 在我的数据库中维护一个表[id INT,modelName VARCHAR,datasource VARCHAR,modelConfig TEXT],它可以保存任何其他表的模型定义

  • 在环回中创建一个模型(称为X),以便在此表上提供CRUD操作

  • 在X中创建remoteMethod以更新应用程序对象中的模型并附加到任何数据源。 实现片段如下所示:

  • X.updateModel=(modelName,cb)=>{
    设app=X.app;
    if(modelName){
    发现({
    其中:{
    名称:modelName
    }
    },函数(错误,结果){
    result.forEach(行=>{
    让{
    数据源,
    模型配置
    }=行;
    //创建一个新模型
    createAndAttachModel(app,datasource,JSON.parse(modelConfig));
    });
    });
    cb(空,“创建:”+modelName);
    }
    };
    X.remoteMethod('updateModel'{
    接受:{arg:'name',type:'string'},
    返回:{arg:'result',type:'string'},
    http:{verb'get'},
    });
    让createAndAttachModel=(应用程序、数据源、模型)=>{
    var环回=要求(“环回”);
    试一试{
    //使用从数据库传入的模型创建新的模型对象
    让newModel=loopback.createModel(model);
    //将模型附加到现有数据源
    应用模型(新模型{
    数据源:null,
    公众:是的
    });
    让currDataSource=app.datasources[datasource];
    if(数据源){
    newModel.attachTo(currDataSource);
    }否则{
    错误(数据源“未初始化”);
    }
    }捕获(错误){
    控制台错误(error);
    }
    
    };很好…)。。但是,当你的应用程序重新启动时,所有这些动态添加的端点不是都消失了吗?也许您还需要通过编程方式将JS代码添加到文件中..我不确定您的意思。。。这是JS代码。。。在你的环回应用程序中。每次应用程序启动时都会创建端点。我还需要在哪里添加它们?有没有一种方法可以在运行时在代码中添加新的端点而无需重新启动节点?例如,我们的用户可以通过UI添加新表和修改现有表。但是,我们需要一个基于公共节点的RESTAPI。这意味着,一旦为特定客户的数据库更改了模式,我们就需要API来公开每个客户的自定义模式,而无需求助于客户特定的节点实例,如果我们确实需要为每个客户数据库提供特定于客户的节点实例,那么有没有一种方法可以直接提供模式以进行环回,而无需通过在磁盘上的json文件中创建和复制模型的额外步骤。也就是说,一切都来自数据库,模式配置保持完全动态