后端与接口
开发 Medusa 后端功能时如何遵循模块→工作流→API…
在规划、研究或实现任何 Medusa 后端功能(自定义模块、API 路由、工作流、数据模型、模块链接、业务逻辑)时,按分层架构与规则清单正确落地。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
开发 Medusa 后端功能时如何遵循模特定
解决思路
- 严格遵循分层数据流:Module(数据模型 + CRUD)→ Workflow(业务逻辑 + 带回滚的变更)→ API Route(HTTP 接口 + 校验中间件)→ Frontend(通过 SDK 调用),绝不跨层绕过。
- HTTP 方法只用 GET、POST、DELETE,绝不用 PUT/PATCH。
- 所有变更操作必须通过 workflow 实现,绝不在路由中直接调用模块服务。
- 业务逻辑放在 workflow step 中,而不是 API 路由中;模块保持简单(仅 CRUD)。
- 跨模块数据检索用 query.graph();跨独立模块按链接字段过滤用 query.index()(Index Module)。
- 用 module links 维持模块间隔离,不要直接跨模块调用服务。
- 使用 req.queryConfig 时不要显式设置 fields。
- 使用 req.validatedBody 时,把 Zod 推断类型传给 MedusaRequest<T>。
- 受保护路由使用 AuthenticatedMedusaRequest,而不是 MedusaRequest。
- 从中间件文件同时导出 Zod schema 和推断类型。
- 绝不给数据模型加 .linkable()(会自动添加)。
- 模块名必须用 camelCase,绝不用短横线(会导致运行时错误)。
- 在 workflow step 中做业务校验,而不是在 API 路由中。
- 在 workflow 中校验归属/权限,而不是在路由中。
- 在文件顶部静态导入 workflows/modules,绝不在路由函数体内用 await import()。
- 所有依赖使用静态导入,避免动态导入(增加开销并破坏类型检查)。
- 从 @medusajs/framework/zod 导入 Zod,绝不直接从 zod 导入;Medusa 自 v2.14.0 起使用 Zod v4:用 z.email()/z.url()/z.uuid() 替代 z.string().email() 等,用 .extend(other.shape) 替代 .merge(other),用 z.strictObject()/z.looseObject() 替代 .strict()/.passthrough(),用 z.enum(MyEnum) 替代 z.nativeEnum(),用 z.record(z.string(), value) 替代 z.record(value)。
- 价格按原值存储(49.99 存为 49.99,不是分):保存时绝不乘 100,展示时绝不除 100。
- 单模块分页查询用 listAndCount。
- query.graph() 不能按链接模块字段过滤——改用 query.index() 或直接从该实体查询。
- 不要对链接数据用 JavaScript .filter(),改用数据库过滤(query.index() 或直接查询该实体)。
- 同一模块内的关联可以用 query.graph() 过滤(如 product.variants)。
- 信任 authenticate 中间件,不要手动检查 req.auth_context。
- workflow step 建议放在 src/workflows/steps/[name].ts,组合函数放在 src/workflows/[name].ts,模块链接定义放在 src/links/[name].ts。
- workflow 组合函数必须用普通 function(非 async、非箭头函数),step 调用不加 await,返回 new WorkflowResponse(result)。
- workflow 中禁止 async/await、箭头函数、条件/三元(用 when())、变量操作(用 transform())、创建日期(用 transform())。
- 多次调用同一步骤时用 .config({ name: "unique-name" }) 避免冲突。
- 实现前对照常见错误清单自查:架构、类型安全、业务逻辑、导入、数据访问五类反模式。
- 实现完成后必须运行构建命令(npm run build / pnpm build / yarn build)捕获类型与运行时错误,构建失败时阅读错误、修复后重跑,未通过不得标记完成。
- 若项目有 @medusajs/eslint-plugin 的 eslint.config.*,medusa build 和 medusa develop 默认运行 lint 并在错误时失败,应修复而非传 --no-lint;用 npx medusa lint(支持 --fix 和 --quiet)显式运行。
- 若项目无 ESLint 配置,可建议添加 @medusajs/eslint-plugin、eslint、jiti 作为 devDependencies 并创建导出 defineConfig([...medusa.configs.recommended]) 的 eslint.config.ts,但不要未经请求就添加。
- 实现完成后向用户提供后续步骤:启动开发服务器(npm run dev / pnpm dev / yarn dev)、访问 http://localhost:9000/app 管理后台、列出所实现的 API 路由及 cURL 测试示例、说明 workflow/订阅者/定时任务的测试要点。
- 前端集成必须使用 Medusa JS SDK:内置端点用现有 SDK 方法(sdk.admin.product.list()、sdk.store.product.list()),自定义路由用 sdk.client.fetch("/admin/my-route") 或 sdk.client.fetch("/store/my-route"),绝不用普通 fetch()(会因缺少认证头或 publishable API key 报错)。
- 实现具体组件前必须加载对应参考文件:custom-modules.md、workflows.md、api-routes.md、module-links.md、querying-data.md、authentication.md 等,至少加载 1-2 个相关参考文件。
- 规划与实现时优先查阅本技能(主要来源),MedusaDocs MCP 服务器仅作为次要来源查询具体方法签名、内置模块配置、官方类型定义和框架级配置。
适用边界 · 注意事项
- 非 Medusa 项目或非 Medusa 后端开发任务。
- 仅需查询具体方法签名、内置模块配置或官方类型定义时,应改用 MedusaDocs MCP 服务器。
- 构建前端管理后台 UI 或 storefront 时,应加载 building-admin-dashboard-customizations 或 building-storefronts 技能。