【问题标题】:Separate model definitions and model code分离模型定义和模型代码
【发布时间】:2018-04-23 22:33:40
【问题描述】:

我希望重新使用模型的 .json - 文件并在不同的服务之间共享它们。这些服务有非常不同的关注点,但希望在相同的数据结构上进行操作。为了避免重复工作和错误,我想将 .json - 文件放入一个包中,并将 Javascript - 文件与每个项目中的模型文件分别关联。示例:

仅用于 .json 定义的目录,可以在访问同一数据源的各种应用程序之间共享:

models 
- ModelA.json
- ModelB.json
- ...

每个应用程序都有一个具有应用程序特定逻辑的目录:

model-logic
- ModelA.js
- ModelB.js
- ...

如果我尝试使用环回,可以找到模型文件,但除非 Javascript 文件位于同一目录中,否则它们与模型无关。有没有办法做到这一点?

【问题讨论】:

    标签: loopbackjs strongloop loopback


    【解决方案1】:

    免责声明:我是 LoopBack 的维护者,也是 loopback-boot 模块的作者。

    在 LoopBack 中,我们有一组用于注册新模型的 API,然后是一个传统的引导程序(loopback-boot 模块),它定义了项目布局的约定并调用 LoopBack API 以自动从 JSON 和 JS 加载和定义模型文件。正如您正确观察到的,loopback-boot 假定 JS 和 JSON 文件位于同一位置。

    为了支持每个应用程序都想定义自定义模型方法的情况,我想到的解决方案很少。

    选项 1:模型继承

    您可以利用模型继承:

    • 共享模块(包)中定义的模型仅提供属性(数据架构)。
    • 对于每个共享模型,应用程序可以定义一个继承自共享模型的子类模型。 JSON 文件可以非常简单(只需模型 namebase 要继承的模型名称,以及自定义方法的远程元数据)。

    包含共享模型的包:

    - BaseModelA.json
    - (empty BaseModelA.js that can be omitted)
    - BaseModelB.json
    - (empty BaseModelB.js that can be omitted)
    - ...
    

    在您的应用中,让我们创建继承自 ModelB 并添加其他行为的 ModelA:

    • common/models/ModelA.json

      {
        "name": "ModelA",
        "base": "BaseModelA",
      }
      
    • common/models/ModelA.js

      'use strict';
      
      module.exports = function(ModelA) {
        // place your code here
      }
      

    缺少的部分是告诉 loopback-boot 在您的共享包中查找模型。假设您的包名为“models”,包含common/models 目录中的模型并安装到node_modules/models,您需要编辑您的server/model-config.json,如下所示:

    {
      "_meta": {
        "sources": [
          "loopback/common/models",
          "loopback/server/models",
          "models/common/models", // <-- ADD THIS LINE
          "../common/models",
          "./models"
        ],
        // etc.
      },
      // etc.
    }
    

    选项 2:按照自己的方式加载模型

    或者,您不必使用 loopback-boot 来设置应用程序运行时,您可以编写自己的常规引导程序。

    以下是要使用的 API:

    • 数据源通过app.dataSource(name, config) (apidocs) 定义。为了定义数据源,loopback-boot 本质上是加载 datasources.json 并遍历所有顶级属性,调用 app.dataSource(key, data[key])

    • 模型分多个步骤加载:

      1. 如果您使用的是 mixins,那么您需要先加载它们。 API 未在 app 级别浮出水面,您必须调用 app.registry.modelBuilder.mixins.define(fn) (source)。

      2. 首先需要通过调用app.registry.createModel(config) 来定义模型,其中config 参数设置为模型JSON 文件的内容。

      3. 拥有模型构造函数后,您需要将其附加到数据源并通过调用app.model(ModelCtor, config) 通过 REST API 公开它。 config 参数包含来自server/model-config.json 文件的模型配置,例如{dataSource: 'db', public: true}

    要加载剩余的工件(应用配置、中间件配置、组件等),最好继续使用 loopback-boot。只需告诉引导程序没有要加载的模型或数据源即可。

    const app = loopback();
    
    // 1. load your datasources and models
    // (TODO)
    
    // 2. use loopback-boot to do the rest
    boot(
      app, 
      {
        appRootDir: __dirname, 
        models: {}, 
        dataSources: {},
        modelSources: [],
        mixinSources: [],
      });
    
    // etc.
    

    (上面的例子是针对loopback-boot@2.x的,我对新版本loopback-boot@3.x的配置选项不太熟悉。)

    【讨论】:

    • 在我们的例子中,继承并没有减少多少工作量,而且使代码有些膨胀。我试了一下,发现它没有胃口。我阅读了环回 3.x 方式的源代码(这是我们正在使用的)。在 compiler.js 方法中,您可以看到模型 .js 文件应该与 model.json 文件并置。我对以这种方式“修补”框架持怀疑态度。以我的经验,这对升级非常脆弱。然而,在这种情况下,它可能是我们权衡复制和粘贴的唯一选择。
    • 我喜欢 model-config.json 文件中的高级选项,它允许将 .json 文件与 .js 文件链接。我认为这样做的努力是可以管理的。类似“modelCodeDirectory”的东西。您认为可以将其添加到功能列表中吗?
    • @IonTichy 我担心 StackOverflow 不太适合这个讨论,请您在github.com/strongloop/loopback-boot 中打开一个问题并提及我的 GitHub 句柄 (bajtos) 以便我收到通知?
    猜你喜欢
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 2016-07-17
    • 2016-11-28
    相关资源
    最近更新 更多