☰
LoopBack 4 模型(Model)完全指南:@model 与 @property 装饰器实战
2026/10/14 1:58:00 网站建设 项目流程
  • 后端
  • 微服务

【免费下载链接】loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.

项目地址:https://gitcode.com/gh_mirrors/lo/loopback-next
点击查看免费下载

本文是 LoopBack 4(loopback-next仓库)中Model概念的技术指南,围绕 docs/site/Model.md 展开,系统讲解如何用@model与@property装饰器定义领域模型、配置模型元数据、隐藏属性、默认作用域、ID 属性、数组属性、自定义校验规则,以及模型与数据库表/集合的映射和 JSON Schema 推断。读完本文,你将掌握在 LoopBack 4 应用中从零定义Entity/Model领域对象并安全对接 REST、OpenAPI 与各类数据库连接器的完整实战能力。

什么是 LoopBack 4 模型(Model)

在 LoopBack 4 中,模型(Model)用来描述业务领域对象(domain objects),例如Customer、Address、Order。一个模型通常定义一组属性(property),每个属性带有名称、类型以及其他约束。

关键设计理念是:模型只描述数据的形状(shape),行为(如 CRUD 操作)由仓库(Repository)添加。这与 LoopBack 3.x 中"模型也实现行为"的旧模式有本质区别;同时,同一个模型可以与多个不同的 Repository 搭配使用。

模型可被用于在线(wire)传输或系统间的数据交换。例如,一个符合Customer模型定义的 JSON 对象,可以被放到 REST/HTTP 请求体中来创建新客户,也可以存入 MongoDB 这类文档数据库。模型定义还能映射为其他形式——关系数据库 Schema、XML Schema、JSON Schema、OpenAPI Schema 或 gRPC 消息定义,反之亦然。

Entity 与 Model:两种细微不同的领域对象

LoopBack 4 将领域对象区分为两类:

  • Entity(实体):拥有身份标识(ID)的领域对象,其相等性基于身份。例如Customer应建模为Entity,因为每个客户都有唯一的 customer id,两个具有相同 customer id 的Customer实例指向同一个客户,因此相等。
import {Entity, model, property} from '@loopback/repository'; @model() export class Customer extends Entity { @property({id: true}) id: string; @property() name: string; @property() email: string; constructor(data?: Partial<Customer>) { super(data); } }
  • Model(模型):没有身份标识的领域对象,其相等性基于结构值(structural value)。例如Address可建模为Model,因为两个美国地址只要街道号、街道名、城市和邮编相同,就是相等的。
import {Model, model, property} from '@loopback/repository'; @model() export class Address extends Model { @property() streetNum: number; @property() streetName: string; @property() city: string; @property() zipCode: string; constructor(data?: Partial<Address>) { super(data); } }

当前项目通过@loopback/repository模块提供专用装饰器@model和@property,用于为 TypeScript/JavaScript 类附加元数据。在源码中,Model与Entity的基类都定义于 packages/repository/src/model.ts:Model提供toJSON()/toObject()序列化能力,Entity extends Model额外提供getId()、getIdObject()、getIdProperties()、buildWhereForId()等与主键相关的工具方法。

定义模型:@model 与 @property 基础用法

一个典型的 LoopBack 4 模型用 TypeScript 编写,使用@model装饰类、@property装饰类成员(属性):

import {Entity, model, property} from '@loopback/repository'; @model({setting: {hiddenProperties: 'id'}}) export class User extends Entity { @property({ type: 'number', id: true, generated: true, }) id: number; @property({ type: 'string', required: false, }) des?: string; constructor(data?: Partial<User>) { super(data); } }

LoopBack 4 还提供了命令行工具(CLI)lb4 model来生成模型。从源码看,CLI 生成器位于 packages/cli/generators/model/index.js,它会依次提示模型名称、基类(Entity/Model)以及需要添加的属性,直到输入空白属性名为止。

本质上,LoopBack 中的模型就是一个简单的 JavaScript 类。借助@model/@property装饰器的可扩展性,框架能够操作元数据,甚至与 JSON Schema 生成集成。例如下面这个不含 ID 的简单模型:

import {model, property} from '@loopback/repository'; @model() export class Customer { @property() email: string; @property() isMember: boolean; @property() cart: ShoppingCart; }

@model装饰器还可以接收jsonSchema来定制为该模型类推断出的 JSON Schema:

@model({ jsonSchema: { title: 'Customer', required: ['email'], }, }) export class Customer { // ... }

模型相关的常见任务

  • 在运行时定义模型:使用defineModelClass()等工具在运行时动态构建模型;
  • 从数据库发现模型:根据数据库现有表/集合反向生成模型定义。

模型元数据:装饰器背后的实现机制

LoopBack 4 通过@model和@property收集模型的元数据。要让这两个装饰器生效,类需要继承Entity(或Model)并使用装饰器标注:

import {model, property, Entity} from '@loopback/repository'; @model() export class Product extends Entity { @property({ id: true, description: 'The unique identifier for a product', }) id: number; @property() name: string; @property() slug: string; constructor(data?: Partial<Product>) { super(data); } }

从源码 packages/repository/src/decorators/model.decorator.ts 可以看到装饰器的真实工作流程:

  • 框架定义了三个元数据访问键(MetadataAccessor):
    • MODEL_KEY('loopback:model'):存储@model传入的ModelDefinitionSyntax;
    • MODEL_PROPERTIES_KEY('loopback:model-properties'):存储@property传入的属性定义;
    • MODEL_WITH_PROPERTIES_KEY('loopback:model-and-properties'):合并后的完整模型定义。
  • @model(definition)装饰器会调用buildModelDefinition(target, def):通过MetadataInspector.getAllPropertyMetadata(MODEL_PROPERTIES_KEY, prototype)收集所有属性元数据;对每个属性,若没有显式type,则回退到 TypeScript 的设计期类型MetadataInspector.getDesignTypeForProperty(...),取不到时抛出错误码为CANNOT_INFER_PROPERTY_TYPE的异常;若属性设置了hidden: true,则自动把该属性名追加进settings.hiddenProperties数组。
  • 最终构建的ModelDefinition被挂在类的definition静态属性上,关系元数据(RELATIONS_KEY)也会被合并进去。

除了定义本身,@model与@property还支持一系列设置。例如,默认情况下 LoopBack 4 类会禁止接收未在类型定义中声明的额外属性;当使用 MongoDB 这类支持自由格式属性的 NoSQL 数据库时,可通过@model关闭该约束。详见下文@model装饰器与@property装饰器两个小节。

@model 装饰器详解:模型定义(ModelDefinitionSyntax)

@model可以不带参数使用,也可以传入ModelDefinitionSyntax对象:

@model({ name: 'Category', settings: { // etc... }, // 属性通过下面的 @property 装饰器定义 }) class Category extends Entity { // etc... @property({type: 'number'}) categoryId: number; }

name可以省略,因为@model装饰器已经知道模型类的名称(源码中通过definition.name ?? target.name回退取类名):

@model() class Product extends Entity { name: string; // other properties... }

注意:如果你用过 LoopBack 3,LB4 的model装饰器与 LB3 并不完全相同。例如,属性(properties)和关系(relations)不能通过model装饰器定义,只能通过@property与关系装饰器完成。请参考下文"支持项"与"不支持项"两节。

模型定义支持项(Supported Entries of Model Definition)

settings中目前内置支持以下条目:

PropertyTypeDefaultDescription
nameStringNone模型名称。
settings.descriptionStringNone模型的可选描述。目前仅支持字符串类型。
settings.forceIdBooleantrue设为true可阻止客户端手动设置自动生成的 ID 值。
settings.hiddenPropertiesArray of StringNone从响应体(.toJSON()输出)中隐藏的属性列表。详见下文 隐藏属性。
settings.scopeObjectN/A作用域,将应用于该模型仓库发起的每一次查询。详见下文 Scope。
settings.strictBoolean or Stringtrue指定模型是否只接受预定义的属性,可选值:
  • true:只接受模型中定义的属性。若模型实例包含未预定义的属性,LoopBack 会抛出ValidationError。SQL 数据库仅支持此模式。
  • false:开放模型,接受所有属性(包括未预定义的)。该模式适合把自由格式的 JSON 数据存入 MongoDB 这类无 Schema 数据库,且仅受此类数据库支持。
  • "filter":只接受模型中定义的属性,但加载/保存含未知属性的实例时静默忽略这些属性,特别适合处理希望"自然淘汰"的旧数据而无需编写迁移脚本的场景。

需要深入源码的读者,可对照查看 legacy-juggler-bridge 与 model-builder 的实现;其中legacy-juggler-bridge.ts中可见创建模型时显式传入{strict: true}等默认配置。

LB3 中不再支持的条目(Unsupported Entries)

如果你是 LB3 用户,以下旧条目在 LB4 中已不可用:

PropertyDescription
acls(待定)
base该条目不再使用。LB4 采用 TypeScript/JavaScript 常规的类继承方式:@model() class MySuperModel extends MyBaseModel {...}
excludeBaseProperties(待定)
http该条目在 LB3 中影响 HTTP 配置。LB4 中 HTTP 配置由控制器成员与 REST 服务器推断,此字段不再适用。
options(待定)
plural属于 LB3 的 HTTP 配置的一部分,与http一样不再适用。
properties不再使用,LB4 引入了@property装饰器来定义模型属性。
relations随着仓库(Repository)的引入,LB4 中关系由关系装饰器定义,参见 Relations。
remoting.normalizeHttpPath属于 LB3 的 HTTP 配置的一部分,不再适用。
replaceOnPUT不再支持:LB4 控制器脚手架生成的 PUT 始终调用replaceById,如需可自行修改生成代码改用patchById。

隐藏属性(Hidden Properties)

隐藏属性仍然存储于数据库、在 JS/TS 代码中可访问、可通过 POST/PUT/PATCH 请求设置,但它们会从响应体(.toJSON()输出)中被移除。典型的应用场景是密码字段等敏感数据。

隐藏属性有两种配置方式:

方式一:模型级hiddenProperties设置(还可以隐藏从父模型继承来的属性):

@model({ settings: { hiddenProperties: ['password'] } }) class MyUserModel extends Entity { @property({id: true}) id: number; @property({type: 'string'}) email: string; @property({type: 'string'}) password: string; ... }

方式二:属性级hidden: true:

@model() class MyUserModel extends Entity { @property({id: true}) id: number; @property({type: 'string'}) email: string; @property({type: 'string', hidden: true}) password: string; ... }

从源码看,属性级hidden: true在buildModelDefinition阶段就会被收集并合并进settings.hiddenProperties(见 packages/repository/src/decorators/model.decorator.ts);而Model.toJSON()在序列化时逐个属性检查hiddenProperties并跳过其中的键(见 packages/repository/src/model.ts)。

Scope:模型级默认查询作用域

Scope允许你设置一个作用于模型仓库每一次查询的默认范围。若希望某个范围应用到所有查询,就在@model的settings.scope中声明。例如:

@model({ settings: { scope: { limit: 2, where: {deleted: false} }, } }) export class Product extends Entity { ...

此后,任何带查询参数的 CRUD 操作都会在默认作用域下执行。例如,假设有上述 scope,一次find调用:

await ProductRepository.find({offset: 0});

等价于:

await ProductRepository.find({ offset: 0, limit: 2, where: {deleted: false}, });

@property 装饰器详解

LoopBack 4 使用@property装饰器定义模型属性:

@model() class Product extends Entity { @property({ name: 'name', description: "The product's common name.", type: 'string', }) public name: string; @property({ type: 'number', id: true, }) id: number; }

属性定义通用属性表

以下是属性定义(PropertyDefinition)的通用字段:

KeyRequired?TypeDescription
defaultNoAny*属性的默认值,类型必须与type一致。注意:如果同时设置了default和required: true,POST/PUT 请求体仍需包含该字段——因为 LoopBack 遵循 OpenAPI 标准,required意味着用户必须始终在请求中提供该字段。
defaultFnNoString用于生成默认值的函数名,必须是以下之一:
  • "guid":基于计算机 MAC 地址与当前时间生成全局唯一标识符(UUID v1)。
  • "uuid":同上,生成 UUID v1。
  • "uuidv4":使用 UUID v4 算法生成。
  • "now":使用new Date()返回的当前日期时间。
注意:
  • defaultFn的值由 LoopBack 自身生成;若想使用数据库内置的uuid函数(如 MySQL、PostgreSQL),请查阅对应连接器的 README。
  • 使用defaultFn时不要设置generated: true,因为generated表示值由数据库而非 LoopBack 生成。
  • 使用defaultFn时也不要设置required: true,因为required意味着用户必须始终提供该字段。
descriptionNoString or Array属性的文档说明。长描述可以拆成字符串数组(多行)以保持行宽可控,例如:["LoopBack 4 is a highly extensible Node.js and TypeScript framework", "for building APIs and microservices.", "..."]
docNoString属性文档。已废弃,请改用description。
idNoBoolean该属性是否为唯一标识,默认false。详见下文 ID 属性。
indexNoBoolean | Object布尔值表示该属性是否为数据库索引列(字段);也可以是对象,如index: {unique: true}让属性唯一。注意:是否支持取决于连接器。
requiredNoBoolean创建或更新模型实例时,请求体是否必须包含该属性,默认false。注意:遵循 OpenAPI 标准,即使设置了default,POST/PUT 请求缺省该字段仍可能被拒绝。
typeYesString属性类型,可以是 LoopBack 类型 中描述的任何类型。
hiddenNoBoolean从响应体(.toJSON()输出)隐藏该属性。详见上文 隐藏属性。

ID 属性

LoopBack 4 期望每个模型都有一个能唯一标识模型实例的ID 属性(ID property)。

重要:LB4 目前不支持复合键(composite keys),例如用多个源键关联两张表。

要显式指定某个属性为 ID,将选项中的id设为true。id的值只能是:

  • true:该属性是 ID;
  • false(或任何可转换为 false 的值):该属性不是 ID(默认)。

在数据库术语中,ID 属性就是主键列(primary key column)。例如:

@property({ type: 'number', id: true, }) id: number;

LoopBack 的 自动迁移(auto-migration)可以根据模型定义创建关系数据库 Schema。以下是可用于 auto-migration / auto-update 的 ID 属性设置:

KeyRequired?TypeDescription
generatedNoBoolean用于 auto-migrate。表示 ID 将由数据库自动生成。设为true时,id 值将由数据库按其默认类型生成(如 MySQL 为 integer、MongoDB 为 string)。
useDefaultIdTypeNoBoolean用于 auto-migrate。需要自动生成非默认类型的属性值时设为false。例如 PostgreSQL 想用 uuid 作为 id:id 类型设为 string、generated设为true、useDefaultIdType设为false。具体请查阅各连接器的 README。

关于 ID 的实用提示:

  1. 如果模型由数据库支撑,LoopBack 的 CRUD 方法要求模型拥有id属性;
  2. 没有任何id属性的模型只能在不挂接数据库的情况下使用;
  3. 若 ID 属性generated为true,由连接器决定自动生成键的类型(例如 SQL Server 默认为number),可通过useDefaultIdType: false覆盖;
  4. 若希望 LoopBack 4 基于模型定义自动创建关系数据库 Schema,参见 Database Migration;数据库迁移/发现的细节与示例始终以 Database Connectors 为准。

在源码 packages/repository/src/model.ts 中可以看到一个联动逻辑:当ModelDefinition.addProperty检测到属性同时满足id === true、generated === true且未显式声明useDefaultIdType时,会自动把useDefaultIdType置为false。

数组属性装饰器(@property.array)

由于 JavaScript 数组本身不携带成员类型信息(遍历数组只能判断成员是原始类型、对象还是函数,无法知道对象/函数的具体结构),LoopBack 无法自动推断数组元素的类型。因此要求使用@property.array装饰器来补充数组属性的类型推断元数据:

@model() class Order extends Entity { @property.array(Product) items: Product[]; } @model() class Thread extends Entity { // 注意:即使是原始类型数组也必须使用! @property.array(String) posts: string[]; }

@property.array还支持可选的第二参数,以与@property相同的方式定义或覆盖元数据:

@model() class Customer extends Entity { @property.array(String, { name: 'names', required: true, }) aliases: string[]; }

数组元素的 JSON Schema 额外属性可以通过第二参数中的jsonSchema提供:

@model() class Customer extends Entity { @property(String, { jsonSchema: { format: 'email', }, }) email: string; }

对于@property.array,jsonSchema作用于数组元素类型而非数组本身:

@model() class TestModel { @property.array(String, { jsonSchema: { format: 'email', minLength: 5, maxLength: 50, transform: ['toLowerCase'], }, }) emails?: string[]; }

要定义嵌套数组属性,必须提供jsonSchema字段来描述子数组。例如:

@model() class TestModel { // 也可以写成 @property.array('array') @property.array(Array, { jsonSchema: { type: 'array', items: {type: 'string'}, }, }) nestedArr: Array<Array<string>>; }

如果缺少jsonSchema字段,会得到如下报错:

You must provide the "jsonSchema" field when define a nested array property

从源码 packages/repository/src/decorators/model.decorator.ts 可见,@property.array在运行时通过MetadataInspector.getDesignTypeForProperty校验属性设计期类型必须是Array,否则抛出ERR_PROP_NOT_ARRAY('@property.array can only decorate array properties!'),随后以{type: Array, itemType}为基础合并用户定义并委托给@property。

自定义校验规则与自定义错误消息

可以在属性的jsonSchema字段中指定校验规则,并搭配自定义错误消息:

@model() class Product extends Entity { @property({ name: 'name', description: "The product's common name.", type: 'string', // JSON 校验规则 jsonSchema: { minLength: 10, maxLength: 30, errorMessage: 'Name should be between 10 and 30 characters.', }, }) public name: string; }

如果你希望为每条未通过的校验规则返回各自的错误消息,可以把errorMessage配置成对象:

jsonSchema: { minLength: 10, maxLength: 30, errorMessage: { // 对应的错误消息 minLength: 'Name should be at least 10 characters.', maxLength: 'Name should not exceed 30 characters.', } }

关于请求体校验的完整实现细节,请参考 Parsing requests(请求解析)。

属性类型的推断限制

@property装饰器依赖 LoopBack 的 metadata 包来确定属性的类型。目前属性类型必须显式声明——要么写在该属性本身上,要么通过@property的type选项指定。别名类型或从类/接口中抽取的类型(例如public name: OtherClass['otherProperty'])无法正常工作:TypeScript 当前生成元数据的方式存在局限,这类写法会导致属性类型在生成的 OpenAPI 规范中被解析为空对象,而不是期望的类型。

反例(结果会生成"__metadata("design:type", Object)"而非String):

export class StandardUser { public email: string; public anotherProperty: boolean; } @model() export class UserModel { @property() public email: StandardUser['email']; // => 生成 "__metadata("design:type", Object)" 而非 String }

正例(直接声明类型,属性类型信息即为String):

@model() class Product extends Entity { @property() public name: string; // 该属性的类型信息是 String。 }

ENUM 属性(变通方案)

目前enum类型尚未被原生支持。下面是允许你使用该类型的变通方案。

@property装饰器可通过jsonSchema定制模型属性推断出的 JSON Schema。对于enum类型,可以这样用:

enum QueryLanguage { JSON = 'json', SQL = 'sql', MONGO = 'mongo' } // ... @property({ type: 'string', required: true, jsonSchema: { enum: Object.values(QueryLanguage), }, }) queryLanguage: QueryLanguage;

模型如何映射到数据库表/集合

一个常见问题是:如何配置与模型类名不同的自定义表/集合名称?

无论通过 CLI(lb4 model)、模型迁移 还是模型发现建立模型与数据库表/集合的对应关系,模型/属性都会基于某种约定或连接器特定设置映射到对应的表/列。

当没有连接器特定设置时,例如:

@model() export class MyModel extends Entity { @property({ type: 'number', required: true, id: true, }) id: number; @property({ type: 'string', required: false, }) myName?: string; }

连接器会按各自的约定映射:以 Oracle 连接器为例,它会在默认 Schema 下寻找名为MYMODEL的表,并把属性id、myName映射为表中的ID、MYNAME列——因为 UPPERCASE(大写)是 Oracle 数据库的默认命名习惯。PostgreSQL 连接器则会在默认 Schema 下寻找小写表名mymodel以及列id、myname。一方面,如果数据库已有默认命名的表/列会很方便;另一方面,如果找不到默认名称的表/列就会带来麻烦。

重要:不同数据库连接器的具体机制可能有差异(例如有的没有schema概念;并非所有连接器都支持自定义配置,如 Cloudant)。务必查阅对应的数据库连接器文档。

数据映射属性(Data Mapping Properties)

模型定义的settings中,以下字段通过settings.<connectorName>描述/定制数据库中的 Schema 或表/集合名称:

PropertyTypeDescription
[connectorName].schemaString表所在的 schema。
[connectorName].tableString表名,用于 SQL 数据库。
[connectorName].collectionString表名(集合名),用于 NoSQL 数据库。

属性定义的以下通用字段则通过<connectorName>.<propName>描述数据库中的列:

PropertyTypeDescription
columnNameString列名,用于 SQL 数据库。
fieldNameString列名(字段名),用于 NoSQL 数据库。
dataTypeString数据库中定义的数据类型。
dataLengthNumber数据长度。
dataPrecisionNumber数值精度。
dataScaleNumber数值小数位数。
nullableBoolean为true时数据可以为 null。

下面的例子展示了如何在 PostgreSQL 数据库中配置与模型不同的自定义表/列名及其他设置:

@model({ settings: { postgresql: {schema: 'quarter2', table: 'my_model'}, // 自定义名称 }, }) export class MyModel extends Entity { @property({ type: 'number', required: true, id: true, postgresql: { columnName: 'custom_id', dataType: 'integer', dataLength: null, dataPrecision: null, dataScale: 0, nullable: 'NO', }, }) id: number; @property({ type: 'string', required: false, postgresql: { columnName: 'my_name', dataType: 'text', dataLength: 20, dataPrecision: null, dataScale: 0, nullable: 'NO', }, }) myName?: string; }

通过上述映射,可以配置与模型不同的自定义名称。上例中,模型属性id映射到表my_model中的列custom_id。

JSON Schema 推断

使用@loopback/repository-json-schema模块可以从带装饰器的模型构建 JSON Schema。类型信息从@model与@property装饰器中推断;该模块提供getJsonSchema函数读取装饰器存储的元数据来构建模型对应的 JSON Schema:

import {model, property} from '@loopback/repository'; import {getJsonSchema} from '@loopback/repository-json-schema'; @model() class Category { @property() name: string; } @model() class Product { @property({required: true}) name: string; @property() type: Category; } const jsonSchema = getJsonSchema(Product);

上面的jsonSchema会返回:

{ "title": "Product", "properties": { "name": { "type": "string" }, "type": { "$ref": "#/definitions/Category" } }, "definitions": { "Category": { "properties": { "name": { "type": "string" } } } }, "required": ["name"] }

如果模型定义中的某个属性指定了自定义类型,就会为该类型生成引用($ref)字段,并在 Schema 顶层创建definitions子 Schema。definitions子 Schema 会通过递归调用getJsonSchema构建其属性,从而支持复杂、嵌套的自定义类型定义——上例中Product的属性type使用了自定义类型Category,正是这一机制的体现。

从源码 packages/repository-json-schema/src/build-schema.ts 可以看到,getJsonSchema会先按选项键(buildModelCacheKey,如'modelOnly'、'modelWithRelations')在类元数据缓存中查找,未命中时才调用modelToJsonSchema生成并写回缓存,因此重复调用是高效的。配套的getJsonSchemaRef则返回形如{$ref: '#/definitions/Product', definitions: {...}}的引用式 Schema,便于多个端点共享同一份定义。

getJsonSchema还接受JsonSchemaOptions选项对象(同样定义于 build-schema.ts):

  • title?: string:定制生成 Schema 的标题,在使用exclude等选项导致自动标题难以阅读时很有用;
  • includeRelations?: boolean:为模型关系定义导航属性(navigational properties);
  • partial?: boolean | 'deep':将所有属性标记为可选(常用于描述 PATCH 端点的请求体);设为'deep'时对嵌套模型实例同样生效;该选项会被非空的optional覆盖;
  • exclude?: (keyof T)[]:从 Schema 中排除的模型属性列表;
  • optional?: (keyof T)[]:标记为可选的属性列表,非空时覆盖partial。

支持的 JSON 关键字(Supported JSON Keywords)

该特性仍在完善中。

以下是可显式传入装饰器以更好地定制生成 JSON Schema 的关键字:

KeywordsDecoratorTypeDefaultDescription
title@modelstringmodel name模型名称
description@modelstringNone模型描述
array@propertybooleanNone指定属性是否为数组
required@propertybooleanfalse指定属性是否必填

与其他 ORM/ODM 的配合

你可能决定在 LoopBack 应用中使用替代的 ORM/ODM。LoopBack 4 不再要求你以它自己的模型格式提供数据来支撑路由——这意味着你可以自由修改自己的类以适配这些 ORM/ODM。

不过也要注意:提供的 Schema 装饰器对这些 ORM/ODM 将不再起作用;而且某些框架可能提供同名冲突的装饰器(例如另一个@model装饰器),这种情况下可能需要避免使用 LoopBack 自带的 juggler 装饰器。仓库中也有现成的实践参考,例如 Using-Sequelize-with-LoopBack 与 Using-TypeORM-with-LoopBack 分别演示了在 LoopBack 4 中接入 Sequelize 与 TypeORM 的完整方式。

总结

模型是 LoopBack 4 数据层的基石:@model负责把类声明为模型并写入ModelDefinition,@property负责描述每个属性的类型、ID、默认值、必填性与校验规则。两者配合可实现隐藏属性、默认查询作用域、数组与嵌套类型、自定义校验消息、数据库表/集合的定制映射以及 JSON Schema 的自动推断。理解这些装饰器背后基于 metadata 包的元数据机制(packages/repository/src/decorators/model.decorator.ts)与序列化实现(packages/repository/src/model.ts),将帮助你更自如地结合 Repository、Relations 与各类数据库连接器构建完整的业务 API。

  • 后端
  • 微服务

【免费下载链接】loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.

项目地址:https://gitcode.com/gh_mirrors/lo/loopback-next
点击查看免费下载
上一篇:【特别体验】 GeekAI项目未登录状态下访问MJ页面错误分析与修复方案
下一篇:【限时免费】 Vue3-Element-Admin项目中解决Store初始化顺序问题

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询