vtex-io-data-access-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseData Access & Storage Patterns
数据访问与存储模式
When this skill applies
适用场景
Use this skill when the main question is where data should live and how a VTEX IO app should read or write it.
- Designing new data flows for an IO app
- Deciding whether to use app settings, configuration apps, Master Data, VBase, or VTEX core APIs
- Reviewing code that reads or writes large, duplicated, or critical datasets
- Introducing caching layers or derived local views around existing APIs
Do not use this skill for:
- detailed Master Data schema or entity modeling
- app settings or configuration app schema design
- auth tokens or policies such as ,
AUTH_TOKEN, or manifest permissionsSTORE_TOKEN - service runtime sizing or concurrency tuning
当核心问题是确定数据存放位置、以及VTEX IO应用应该如何读写该数据时,可使用本指南:
- 为IO应用设计全新数据流
- 决策是否使用应用设置、配置应用、Master Data、VBase或VTEX核心API
- 审核读写大型、重复或关键数据集的代码
- 为现有API新增缓存层或衍生本地视图
本指南不适用于以下场景:
- 详细的Master Data schema或实体建模
- 应用设置或配置应用的schema设计
- 鉴权令牌或策略,例如、
AUTH_TOKEN或manifest权限配置STORE_TOKEN - 服务运行时规格调整或并发调优
Decision rules
决策规则
Choose the right home for each kind of data
为不同类型的数据选择合适的存储位置
- Use app settings or configuration apps for stable configuration managed by merchants or operators, such as feature flags, credentials, external base URLs, and behavior toggles.
- Use Master Data for structured custom business records that belong to the account and need validation, filtering, search, pagination, or lifecycle management.
- Use VBase for simple keyed documents, auxiliary snapshots, or cache-like JSON payloads that are usually read by key rather than searched broadly.
- Use VTEX core APIs when the data already belongs to a VTEX core domain such as orders, catalog, pricing, or logistics.
- Use external stores or external APIs when the data belongs to another system and VTEX IO is only integrating with it.
- 面向由商家或运营人员管理的稳定配置,例如功能开关、凭证、外部服务基础URL、行为切换项等,使用应用设置或配置应用存储
- 面向属于账户所有、需要校验、过滤、搜索、分页或生命周期管理的结构化自定义业务记录,使用Master Data存储
- 面向简单的键值文档、辅助快照、类缓存JSON载荷(通常通过键查询而非大范围搜索),使用VBase存储
- 若数据已经属于VTEX核心域,例如订单、商品目录、定价、物流相关数据,直接使用VTEX核心API
- 若数据属于其他系统,VTEX IO仅做集成对接,使用外部存储或外部API
Keep source of truth explicit
明确真值源归属
- Treat VTEX core APIs as the source of truth for core commerce domains such as orders, products, prices, inventory, and similar platform-owned data.
- Do not mirror complete orders, catalog records, prices, or inventories into Master Data or VBase unless there is a narrow derived use case with clear ownership.
- If an IO app needs a local copy, store only the minimal fields or derived view required for that app and rehydrate full details from the authoritative source when needed.
- Do not use app settings or configuration apps as generic operational data stores.
- 订单、商品、价格、库存等核心电商域数据,将VTEX核心API作为真值源
- 除非有明确归属的窄范围衍生用例,否则不要将完整订单、商品目录记录、价格或库存镜像存储到Master Data或VBase中
- 若IO应用需要本地副本,仅存储该应用所需的最小字段或衍生视图,需要完整信息时从权威源同步获取
- 不要将应用设置或配置应用作为通用运营数据存储使用
Design reads and caches intentionally
合理设计读操作与缓存策略
- Prefer API-level filtering, pagination, field selection, and bounded reads instead of loading full datasets into Node and filtering in memory.
- Use caching only when repeated reads justify it and the cached view has clear invalidation or freshness rules.
- When a background job or event pipeline needs persistent processing state, store only the status and correlation data required for retries and idempotency.
- Keep long-lived logs, traces, or unbounded histories out of Master Data and VBase unless the use case explicitly requires a durable app-owned audit trail.
- 优先使用API层面的过滤、分页、字段选择、范围读取,而非将全量数据集加载到Node中再做内存过滤
- 仅当重复读取的场景足够支撑缓存收益,且缓存视图有明确的失效或 freshness 规则时,再使用缓存
- 若后台任务或事件管道需要持久化处理状态,仅存储重试和幂等所需的状态与关联数据
- 不要将长期存储的日志、链路追踪或无边界的历史数据存放在Master Data和VBase中,除非用例明确要求应用自有持久化审计 trail
Hard constraints
强制约束
Constraint: Configuration stores must not be used as operational data storage
约束:配置存储不得用作运营数据存储
App settings and configuration apps MUST represent configuration, not transactional records, unbounded lists, or frequently changing operational state.
Why this matters
Using configuration stores as data storage blurs system boundaries, makes workspace behavior harder to reason about, and breaks expectations for tools and flows that depend on settings being small and stable.
Detection
If you see arrays of records, logs, histories, orders, or other growing operational payloads inside , configuration app payloads, or settings-related APIs, STOP and move that data to Master Data, VBase, a core API, or an external store.
settingsSchemaCorrect
json
{
"settingsSchema": {
"type": "object",
"properties": {
"enableModeration": {
"type": "boolean"
}
}
}
}Wrong
json
{
"settingsSchema": {
"type": "object",
"properties": {
"orders": {
"type": "array"
}
}
}
}应用设置和配置应用必须仅用于存放配置,不得用于存储事务记录、无边界列表、或频繁变更的运营状态。
重要性说明
将配置存储用作数据存储会模糊系统边界,增加工作空间行为的理解成本,同时会打破依赖「设置小且稳定」特性的工具和流程的预期。
问题识别
如果在、配置应用载荷、或设置相关API中发现记录数组、日志、历史数据、订单或其他不断增长的运营类载荷,请立即停止,将该类数据迁移到Master Data、VBase、核心API或外部存储中。
settingsSchema正确示例
json
{
"settingsSchema": {
"type": "object",
"properties": {
"enableModeration": {
"type": "boolean"
}
}
}
}错误示例
json
{
"settingsSchema": {
"type": "object",
"properties": {
"orders": {
"type": "array"
}
}
}
}Constraint: Core systems must remain the source of truth for their domains
约束:核心系统必须保留对应域的真值源地位
VTEX core systems such as Orders, Catalog, Pricing, and Logistics MUST remain the primary source of truth for their own business domains.
Why this matters
Treating a local IO copy as the main store for core domains creates reconciliation drift, stale reads, and business decisions based on outdated data.
Detection
If an app stores full order payloads, product documents, inventory snapshots, or price tables in Master Data or VBase and then uses those copies as the main source for business decisions, STOP and redesign the flow around the authoritative upstream source.
Correct
typescript
const order = await ctx.clients.oms.getOrder(orderId)
ctx.body = {
orderId: order.orderId,
status: order.status,
}Wrong
typescript
const cachedOrder = await ctx.clients.masterdata.getDocument({
dataEntity: 'ORD',
id: orderId,
})
ctx.body = cachedOrderVTEX核心系统(例如订单、商品目录、定价、物流系统)必须保留对应业务域的首要真值源地位。
重要性说明
将IO应用的本地副本作为核心域的主存储会导致数据一致性偏移、读取过期数据,以及基于过时数据做出错误业务决策的问题。
问题识别
如果应用将完整订单载荷、商品文档、库存快照、价格表存储在Master Data或VBase中,并将这些副本作为业务决策的主要数据源,请立即停止,围绕上游权威源重新设计流程。
正确示例
typescript
const order = await ctx.clients.oms.getOrder(orderId)
ctx.body = {
orderId: order.orderId,
status: order.status,
}错误示例
typescript
const cachedOrder = await ctx.clients.masterdata.getDocument({
dataEntity: 'ORD',
id: orderId,
})
ctx.body = cachedOrderConstraint: Data-heavy reads must avoid full scans and in-memory filtering
约束:大量数据读取必须避免全量扫描和内存过滤
Large or growing datasets MUST be accessed through bounded queries, filters, pagination, or precomputed derived views instead of full scans and broad in-memory filtering.
Why this matters
Unbounded reads are inefficient, hard to scale, and easy to turn into fragile service behavior as the dataset grows.
Detection
If you see code that fetches entire collections from Master Data, VTEX APIs, or external stores and then filters or aggregates the result in Node for a normal request flow, STOP and redesign the access path.
Correct
typescript
const documents = await ctx.clients.masterdata.searchDocuments({
dataEntity: 'RV',
fields: ['id', 'status'],
where: 'status=approved',
pagination: {
page: 1,
pageSize: 20,
},
})Wrong
typescript
const allDocuments = await ctx.clients.masterdata.scrollDocuments({
dataEntity: 'RV',
fields: ['id', 'status'],
})
const approved = allDocuments.filter((doc) => doc.status === 'approved')对于大型或持续增长的数据集,必须通过范围查询、过滤、分页或预计算的衍生视图访问,不得使用全量扫描和大范围内存过滤。
重要性说明
无边界读取效率低下、难以扩展,且随着数据集增长很容易导致服务行为不稳定。
问题识别
如果发现代码从Master Data、VTEX API或外部存储拉取整个集合,然后在Node中过滤或聚合结果用于常规请求流程,请立即停止,重新设计访问路径。
正确示例
typescript
const documents = await ctx.clients.masterdata.searchDocuments({
dataEntity: 'RV',
fields: ['id', 'status'],
where: 'status=approved',
pagination: {
page: 1,
pageSize: 20,
},
})错误示例
typescript
const allDocuments = await ctx.clients.masterdata.scrollDocuments({
dataEntity: 'RV',
fields: ['id', 'status'],
})
const approved = allDocuments.filter((doc) => doc.status === 'approved')Preferred pattern
推荐模式
Start every data design with four questions:
- Whose data is this?
- Who is the source of truth?
- How will the app query it?
- Does the app really need to store a local copy?
Then choose intentionally:
- app settings or configuration apps for stable configuration
- Master Data for structured custom records owned by the app domain
- VBase for simple keyed documents or cache-like payloads
- VTEX core APIs for authoritative commerce data
- external stores or APIs for data owned outside VTEX
If the app stores a local copy, keep it small, derived, and clearly secondary to the authoritative source.
所有数据设计都从四个问题开始:
- 这个数据归谁所有?
- 真值源是谁?
- 应用会如何查询这个数据?
- 应用是否真的需要存储本地副本?
然后针对性选择存储方案:
- 稳定配置使用应用设置或配置应用
- 应用域自有的结构化自定义记录使用Master Data
- 简单键值文档或类缓存载荷使用VBase
- 权威电商数据使用VTEX核心API
- VTEX外部所有的数据使用外部存储或API
如果应用需要存储本地副本,保证副本足够小、是衍生数据、且明确是权威源的二级副本。
Common failure modes
常见故障模式
- Using app settings as generic storage for records, histories, or large lists.
- Mirroring complete orders, products, or prices from VTEX core into Master Data or VBase as a parallel source of truth.
- Fetching entire datasets only to filter, sort, or aggregate them in memory for normal request flows.
- Using Master Data or VBase for unbounded debug logs or event dumps.
- Adding caches without clear freshness, invalidation, or ownership rules.
- Spreading ad hoc data access decisions across handlers instead of keeping source-of-truth and storage decisions explicit.
- 将应用设置作为记录、历史数据或大型列表的通用存储
- 将VTEX核心的完整订单、商品、价格镜像到Master Data或VBase中作为并行真值源
- 拉取全量数据集后在内存中过滤、排序或聚合用于常规请求流程
- 使用Master Data或VBase存储无边界的调试日志或事件转储
- 新增缓存时没有明确的新鲜度、失效或归属规则
- 临时的 data access 决策散落在各个 handler 中,没有明确的真值源和存储决策
Review checklist
审核检查清单
- Is this data truly configuration, or should it live in Master Data, VBase, a core API, or an external system?
- Is the authoritative source of truth explicit?
- Is VTEX core being treated as authoritative for orders, catalog, prices, inventory, and similar domains?
- Is local storage limited to data the app truly owns or a narrow derived view?
- Are reads bounded with filters, field selection, and pagination where appropriate?
- Does any cache or local copy have clear freshness and invalidation rules?
- 该数据确实是配置吗?还是应该存放在Master Data、VBase、核心API或外部系统中?
- 权威真值源是否明确?
- 订单、商品目录、价格、库存等同类域是否将VTEX核心作为权威源?
- 本地存储是否仅限应用真正自有数据或窄范围衍生视图?
- 读操作在合适的场景下是否通过过滤、字段选择、分页做了范围限制?
- 所有缓存或本地副本是否有明确的新鲜度和失效规则?
Related skills
相关指南
- - Use when the main decision is how to model app-level configuration
vtex-io-app-settings - - Use when shared structured configuration should be injected through
vtex-io-service-configuration-appsctx.vtex.settings - - Use when the main decision is whether Master Data is the right storage mechanism and how to model it
vtex-io-masterdata-strategy
- - 适用于核心决策为如何建模应用级配置的场景
vtex-io-app-settings - - 适用于共享结构化配置需要通过
vtex-io-service-configuration-apps注入的场景ctx.vtex.settings - - 适用于核心决策为Master Data是否是合适的存储机制、以及如何建模的场景
vtex-io-masterdata-strategy
Reference
参考资料
- Master Data - Structured account-level custom data storage
- VBase - Key-value storage and JSON blobs for VTEX IO apps
- Calling VTEX commerce APIs using VTEX IO clients - How to consume Orders, Catalog, Pricing, and other core APIs from VTEX IO
- Configuring your app settings - App settings as configuration rather than operational storage
- Creating an interface for your app settings - Public versus private app settings and config boundaries
- Master Data - 结构化账户级自定义数据存储
- VBase - 面向VTEX IO应用的键值存储和JSON blob存储
- Calling VTEX commerce APIs using VTEX IO clients - 如何在VTEX IO中调用订单、商品目录、定价等核心API
- Configuring your app settings - 应用设置是配置而非运营存储
- Creating an interface for your app settings - 公开与私有应用设置及配置边界