生产级 Shopify Function 的难点不是写出一次正确输出,而是让规则在大购物车、缺失数据、多个函数、版本升级和配置变更下仍可预测。本文聚焦架构、测试和发布治理,不编造“每秒处理多少笔”或虚构品牌案例。
把业务规则写成决策表
在代码前列出条件、优先级、排除、输出和默认行为。例如折扣规则要明确币种、客户资格、组合商品、订阅、退款、其他折扣与市场边界。同一个自然语言“VIP 享折扣”可能包含十几个冲突条件。
| 风险 | 测试样本 | 安全策略 |
|---|---|---|
| 输入缺失 | metafield 不存在 | 使用明确默认值 |
| 数量极大 | 大购物车/多变体 | 控制查询与遍历 |
| 规则冲突 | 多个资格同时满足 | 固定优先级 |
| 配置错误 | 非法值或旧 schema | 拒绝启用并提示 |
| 版本变化 | API 升级 | 固定版本、回归测试 |
控制输入与计算复杂度
GraphQL input query 只请求决策所需字段。避免深层连接、无边界列表和把整套业务数据库复制到 metafields。对于需要外部事实的规则,设计数据同步时间、过期标记和失效默认值。Functions 的价值是受支持执行点的确定性,不是把所有系统逻辑塞进结账路径。
建立四层测试
- 纯规则单元测试:覆盖决策表与边界。
- 本地执行:用真实捕获输入验证 schema 和输出。
- 开发店集成测试:验证商家配置、目标和客户流程。
- 发布后观察:检查执行错误、业务异常和配置采用情况。
Shopify CLI 可流式查看开发店日志并保存输入/输出,用于复现。发布时记录代码版本、API 版本、配置迁移、启用范围和回滚负责人。不要在流量高峰首次启用未经影子测试的核心价格规则。
观察业务不变量
除执行成功外,还要监控“不应改变”的结果:订单总额与组件之和一致、税与折扣口径可解释、被隐藏的支付或配送选项符合市场政策、退款后不会出现负值或重复优惠。为每个不变量建立可查询报表或定期对账,避免函数返回合法 schema 却产生错误业务结果。
当规则数量增长,设置变更评审和冲突清单。一个团队修改会员折扣,另一个团队修改组合折扣时,必须在共同测试矩阵里验证,而不是各自在开发店证明单独正确。
与 Flow、Webhook 和外部服务分层
Functions 只返回受支持操作;Flow 处理运营自动化;Webhook 传递事件;外部服务进行长时计算、集成和对账。通过 Webhook 安全与重试 补齐异步一致性,不要要求 Function 负责整个生命周期。
FAQ
JavaScript 和 Rust 应该选哪个?
看团队能力、目标与数据规模。Shopify 对大购物车性能敏感场景推荐 Rust,但两者都必须经过相同输入测试。
是否应该在 Function 中读取很多 metafield?
只读取决策需要且有治理的数据。过多字段增加复杂度、缺失风险和输入成本。
多个 Functions 冲突怎么办?
先查具体 target 的组合规则,并在业务层定义优先级、排除和验收样本。
如何测试生产数据而不影响客户?
使用开发店与脱敏的生产形态输入,必要时先部署为关闭状态或受限配置。
API 版本升级要做什么?
阅读变更、更新 schema、重跑所有决策和集成测试,并保留可回滚的上一版本。