分离模型定义和模型代码
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 文件可以非常简单(只是要继承的模型
name
和 base
模型名称,可能还有自定义方法的远程处理元数据)。
包含共享模型的包:
- 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])
.
模型分多个步骤加载:
如果你使用mixins,那么你需要先加载它们。 API 未在 app
级别浮出水面,您必须调用 app.registry.modelBuilder.mixins.define(fn)
(source).
首先需要通过调用app.registry.createModel(config)
定义模型,其中config
参数设置为模型JSON文件的内容。
获得模型构造函数后,您需要将其附加到数据源并通过调用 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
的配置选项不熟悉。)
我希望重新使用 .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 文件可以非常简单(只是要继承的模型
name
和base
模型名称,可能还有自定义方法的远程处理元数据)。
包含共享模型的包:
- 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])
.模型分多个步骤加载:
如果你使用mixins,那么你需要先加载它们。 API 未在
app
级别浮出水面,您必须调用app.registry.modelBuilder.mixins.define(fn)
(source).首先需要通过调用
app.registry.createModel(config)
定义模型,其中config
参数设置为模型JSON文件的内容。获得模型构造函数后,您需要将其附加到数据源并通过调用
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
的配置选项不熟悉。)