Skip to Content

引擎架构

Entity Engine 是整个框架的核心,为您的应用提供统一的数据管理、权限控制和业务逻辑处理。通过一个引擎实例,您就可以管理所有的实体模型、处理用户请求、执行业务逻辑。

您只需要初始化一次引擎,就可以在应用的任何地方使用相同的配置和数据。

初始化引擎

在应用中使用 Entity Engine 之前,您需要先初始化一个引擎实例。推荐的做法是创建一个全局的获取函数:

// lib/entity-engine.ts import { EntityEngine } from '@scenemesh/entity-engine/server'; import { PrismaClient } from '@prisma/client'; let engineInstance: EntityEngine | null = null; export async function getEntityEngine(): Promise<EntityEngine> { if (!engineInstance) { const prisma = new PrismaClient(); engineInstance = await EntityEngine.getInstance({ prisma, settings: { debug: process.env.NODE_ENV === 'development' } }); } return engineInstance; }

初始化完成后,您就可以在应用的任何地方获取并使用这个引擎实例。

基本数据操作

连接引擎后,您可以使用统一的接口进行数据操作,无需关心底层的数据库实现细节:

import { getEntityEngine } from './lib/entity-engine'; const engine = await getEntityEngine(); // 查询数据 const users = await engine.datasource.listObjects({ modelName: 'User', pagination: { page: 1, pageSize: 10 } }); // 创建数据 const newUser = await engine.datasource.createObject({ modelName: 'User', values: { name: 'John Doe', email: 'john@example.com' } }); // 更新数据 await engine.datasource.updateObject({ id: newUser.id, values: { name: 'John Smith' } });

所有的数据操作都会自动应用权限检查和业务规则验证。

在 API 路由中使用

Next.js App Router

在 Next.js 的 API 路由中使用引擎处理请求:

// app/api/users/route.ts import { getEntityEngine } from '@/lib/entity-engine'; import { NextRequest, NextResponse } from 'next/server'; export async function GET(request: NextRequest) { try { const engine = await getEntityEngine(); const users = await engine.datasource.listObjects({ modelName: 'User' }); return NextResponse.json(users); } catch (error) { return NextResponse.json( { error: '获取用户列表失败' }, { status: 500 } ); } } export async function POST(request: NextRequest) { try { const engine = await getEntityEngine(); const data = await request.json(); const newUser = await engine.datasource.createObject({ modelName: 'User', values: data }); return NextResponse.json(newUser); } catch (error) { return NextResponse.json( { error: '创建用户失败' }, { status: 500 } ); } }

tRPC 集成

在 tRPC 路由中使用引擎:

// server/api/routers/user.ts import { z } from 'zod'; import { createTRPCRouter, publicProcedure } from '../trpc'; import { getEntityEngine } from '@/lib/entity-engine'; export const userRouter = createTRPCRouter({ list: publicProcedure .input(z.object({ page: z.number().default(1), pageSize: z.number().default(10) })) .query(async ({ input }) => { const engine = await getEntityEngine(); return engine.datasource.listObjects({ modelName: 'User', pagination: input }); }), create: publicProcedure .input(z.object({ name: z.string(), email: z.string().email() })) .mutation(async ({ input }) => { const engine = await getEntityEngine(); return engine.datasource.createObject({ modelName: 'User', values: input }); }), update: publicProcedure .input(z.object({ id: z.string(), data: z.object({ name: z.string().optional(), email: z.string().email().optional() }) })) .mutation(async ({ input }) => { const engine = await getEntityEngine(); return engine.datasource.updateObject({ id: input.id, values: input.data }); }) });

引擎配置

基本配置选项

引擎支持多种配置选项来控制其行为:

const engine = await EntityEngine.getInstance({ prisma: new PrismaClient(), settings: { debug: true, // 开启调试模式,显示详细日志 maxQueryDepth: 10, // 限制关联查询的最大深度 enableQueryCache: true, // 启用查询结果缓存 defaultPageSize: 20 // 默认分页大小 } });

数据库配置

引擎目前支持 PostgreSQL 数据库,通过 Prisma 进行连接:

import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient({ datasources: { db: { url: process.env.DATABASE_URL } }, log: process.env.NODE_ENV === 'development' ? ['query', 'info', 'warn', 'error'] : ['error'] }); const engine = await EntityEngine.getInstance({ prisma });

环境特定配置

根据不同环境调整引擎配置:

// lib/entity-engine.ts export async function getEntityEngine() { const isDevelopment = process.env.NODE_ENV === 'development'; const isProduction = process.env.NODE_ENV === 'production'; return EntityEngine.getInstance({ prisma: new PrismaClient(), settings: { debug: isDevelopment, enableQueryCache: isProduction, maxQueryDepth: isDevelopment ? 20 : 10, defaultPageSize: isDevelopment ? 50 : 20 } }); }

核心子系统

数据源管理

您可以使用数据源工厂来为不同的模型创建数据访问对象:

const engine = await getEntityEngine(); const dataSource = engine.datasourceFactory.getDataSource(); // 所有数据操作都通过统一接口 const result = await dataSource.listObjects({ modelName: 'Post', filter: { status: 'published' }, sort: [{ field: 'createdAt', direction: 'desc' }], pagination: { page: 1, pageSize: 10 } }); console.log(`找到 ${result.total} 篇文章`); console.log('文章列表:', result.items);

模型注册管理

使用模型注册表来管理应用中的所有实体模型:

// 注册新模型 await engine.metaRegistry.updateOrRegister({ name: 'Product', title: '产品', fields: [ { name: 'name', title: '产品名称', type: 'string', isRequired: true }, { name: 'price', title: '价格', type: 'number', isRequired: true }, { name: 'category', title: '分类', type: 'many_to_one', refModel: 'Category' } ] }); // 获取已注册的模型 const productModel = await engine.metaRegistry.getModel('Product'); console.log('产品模型字段:', productModel.fields); // 检查模型是否存在 const hasProduct = await engine.metaRegistry.hasModel('Product');

会话与权限管理

通过会话管理器设置用户认证和权限控制:

// 设置会话提供者 engine.sessionManager.setProvider({ async session() { const session = await getServerSession(); return { id: session.user.id, userId: session.user.id, roles: session.user.roles, permissions: await getUserPermissions(session.user.id) }; } }); // 引擎会自动使用会话信息进行权限检查 const users = await engine.datasource.listObjects({ modelName: 'User' // 会自动检查当前用户是否有读取权限 });

高级查询功能

关联查询

引擎支持自动处理模型间的关联关系:

// 查询文章并包含作者和分类信息 const posts = await engine.datasource.listObjects({ modelName: 'Post', include: { author: true, // 包含作者信息 category: true, // 包含分类信息 tags: true // 包含标签信息 } }); // 结果会自动包含关联数据 posts.items.forEach(post => { console.log(`文章: ${post.title}`); console.log(`作者: ${post.author.name}`); console.log(`分类: ${post.category.name}`); });

复杂过滤条件

支持多种过滤条件组合:

const posts = await engine.datasource.listObjects({ modelName: 'Post', filter: { status: 'published', publishedAt: { gte: new Date('2025-01-01') }, author: { status: 'active' }, OR: [ { category: { name: '技术' } }, { tags: { some: { name: { in: ['JavaScript', 'TypeScript'] } } } } ] } });

排序和分页

灵活的排序和分页支持:

const posts = await engine.datasource.listObjects({ modelName: 'Post', sort: [ { field: 'featured', direction: 'desc' }, // 推荐文章优先 { field: 'publishedAt', direction: 'desc' }, // 按发布时间倒序 { field: 'viewCount', direction: 'desc' } // 按浏览量倒序 ], pagination: { page: 1, pageSize: 20 } }); console.log(`第 ${posts.page} 页,共 ${posts.totalPages} 页`); console.log(`总计 ${posts.total} 篇文章`);

事件系统集成

监听数据变化

当数据发生变化时,您可以通过事件系统监听并响应这些变化:

// 监听所有数据创建事件 engine.eventRegistry.on('entityObject.created', async (event) => { console.log(`创建了新的 ${event.modelName}: ${event.objectId}`); if (event.modelName === 'User') { // 新用户注册后的处理逻辑 await sendWelcomeEmail(event.values.email); await createUserProfile(event.objectId); } }); // 监听特定模型的更新事件 engine.eventRegistry.on('entityObject.updated', async (event) => { if (event.modelName === 'Order' && event.changes.status) { // 订单状态变更时的处理逻辑 await notifyOrderStatusChange(event.objectId, event.changes.status); } });

自定义业务事件

在业务逻辑中触发自定义事件:

async function processOrder(orderId: string) { // 处理订单逻辑 await updateOrderStatus(orderId, 'processing'); // 触发自定义事件 await engine.eventRegistry.emit('order.processing', { orderId, timestamp: new Date() }); } // 其他模块监听这个事件 engine.eventRegistry.on('order.processing', async (event) => { await sendProcessingNotification(event.orderId); await updateInventory(event.orderId); });

模块化扩展

注册模块

使用模块系统来组织相关功能:

const blogModule = { info: { name: 'BlogModule', version: '1.0.0', description: '博客管理模块' }, async setupConfig(args) { // 注册模型 args.models.push( BlogPostModel, BlogCategoryModel, BlogTagModel ); // 注册视图 args.views.push( BlogPostFormView, BlogPostGridView, BlogCategoryView ); }, async setupComponents(args) { // 注册自定义组件 args.widgets.push({ name: 'rich-text-editor', component: RichTextEditor }); } }; // 注册模块到引擎 await engine.moduleRegistry.registerModule(blogModule);

模块生命周期

模块会按照特定的生命周期进行加载:

const userModule = { info: { name: 'UserModule', version: '1.0.0' }, // 1. 配置阶段:注册模型和视图 async setupConfig(args) { args.models.push(UserModel, UserProfileModel); args.views.push(UserFormView, UserListView); }, // 2. 组件阶段:注册UI组件 async setupComponents(args) { args.widgets.push({ name: 'avatar-uploader', component: AvatarUploader }); }, // 3. 数据阶段:初始化默认数据 async setupData(args) { args.entities.push({ modelName: 'UserRole', data: [ { name: 'admin', description: '管理员' }, { name: 'user', description: '普通用户' } ] }); } }; await engine.moduleRegistry.registerModule(userModule);

性能优化

查询缓存

启用查询缓存来提升性能:

const engine = await EntityEngine.getInstance({ prisma, settings: { enableQueryCache: true, cacheMaxAge: 300 // 缓存5分钟 } }); // 相同的查询会使用缓存结果 const users1 = await engine.datasource.listObjects({ modelName: 'User' }); const users2 = await engine.datasource.listObjects({ modelName: 'User' }); // 使用缓存

连接池管理

优化数据库连接池配置:

const prisma = new PrismaClient({ datasources: { db: { url: process.env.DATABASE_URL } }, engineConfig: { connection_limit: 10, // 连接池大小 pool_timeout: 2, // 连接超时时间 statement_cache_size: 100 // 语句缓存大小 } });

批量操作

使用批量操作来提升性能:

// 批量创建用户 const users = await Promise.all([ engine.datasource.createObject({ modelName: 'User', values: userData1 }), engine.datasource.createObject({ modelName: 'User', values: userData2 }), engine.datasource.createObject({ modelName: 'User', values: userData3 }) ]); // 或者使用事务 await engine.datasource.transaction(async (tx) => { await tx.createObject({ modelName: 'User', values: userData1 }); await tx.createObject({ modelName: 'User', values: userData2 }); await tx.createObject({ modelName: 'User', values: userData3 }); });

错误处理

统一错误处理

在应用中处理错误时,可以使用统一的错误处理方式:

try { const user = await engine.datasource.createObject({ modelName: 'User', values: { email: 'invalid-email' } }); } catch (error) { if (error.code === 'VALIDATION_FAILED') { console.error('数据验证失败:', error.details); } else if (error.code === 'PERMISSION_DENIED') { console.error('权限不足:', error.message); } else if (error.code === 'DUPLICATE_KEY') { console.error('数据重复:', error.message); } else { console.error('未知错误:', error); } }

错误监控

设置错误监控来跟踪引擎运行状态:

// 监听引擎错误事件 engine.eventRegistry.on('engine.error', (event) => { console.error('引擎错误:', { type: event.errorType, message: event.message, stack: event.stack, timestamp: new Date() }); // 发送到错误监控服务 sendToErrorMonitoring(event); });

调试和监控

调试模式

在开发环境中启用调试模式:

const engine = await EntityEngine.getInstance({ prisma, settings: { debug: true // 会输出详细的操作日志 } }); // 调试模式下会看到类似这样的日志: // [EntityEngine] 查询模型: User // [EntityEngine] 应用权限过滤: model:User:read // [EntityEngine] 执行数据库查询: SELECT * FROM users WHERE ... // [EntityEngine] 查询结果: 15 条记录

性能监控

监控引擎的性能指标:

// 监控查询性能 engine.eventRegistry.on('datasource.query', (event) => { if (event.duration > 1000) { // 超过1秒的慢查询 console.warn('慢查询检测:', { modelName: event.modelName, duration: event.duration, query: event.query }); } }); // 监控内存使用 setInterval(() => { const memUsage = process.memoryUsage(); console.log('内存使用:', { rss: Math.round(memUsage.rss / 1024 / 1024) + 'MB', heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) + 'MB' }); }, 30000); // 每30秒检查一次

最佳实践

单例模式

确保在整个应用中使用同一个引擎实例:

// ✅ 推荐:创建全局单例 // lib/entity-engine.ts let engineInstance: EntityEngine | null = null; export async function getEntityEngine() { if (!engineInstance) { engineInstance = await EntityEngine.getInstance(config); } return engineInstance; } // ❌ 避免:在多个地方创建实例 const engine1 = await EntityEngine.getInstance(config); // 不要这样做 const engine2 = await EntityEngine.getInstance(config); // 不要这样做

错误边界

在 API 层添加统一的错误处理:

// utils/api-wrapper.ts export function withErrorHandling(handler: Function) { return async (req: Request, res: Response) => { try { return await handler(req, res); } catch (error) { console.error('API 错误:', error); if (error.code === 'PERMISSION_DENIED') { return res.status(403).json({ error: '权限不足' }); } else if (error.code === 'VALIDATION_FAILED') { return res.status(400).json({ error: '输入数据无效', details: error.details }); } else { return res.status(500).json({ error: '服务器内部错误' }); } } }; }

配置管理

将引擎配置集中管理:

// config/entity-engine.ts export const entityEngineConfig = { development: { debug: true, enableQueryCache: false, maxQueryDepth: 20 }, production: { debug: false, enableQueryCache: true, maxQueryDepth: 10 }, test: { debug: false, enableQueryCache: false, maxQueryDepth: 5 } }; export function getEngineConfig() { const env = process.env.NODE_ENV || 'development'; return entityEngineConfig[env]; }

下一步

掌握引擎架构后,您可以:

Last updated on