分离模型定义和模型代码

Separate model definitions and model code

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

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

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

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

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

如果我尝试使用回送,可以找到模型文件,但除非 Javascript 文件位于同一目录中,否则它们与模型无关。有什么办法可以实现吗?

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

在 LoopBack 中,我们有一组 API 用于注册新模型,然后是一个常规的引导程序(loopback-boot 模块),它定义了项目布局的约定并调用 LoopBack APIs 从 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}.

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

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的配置选项不熟悉。)