
Metabase Embedding SDK 中的 SdkQuestionId 类型详解数值 ID、实体 ID 与新建问题模式【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabaseSdkQuestionId 是 Metabase Embedding SDK 中用于标识 Question问题的统一类型它同时覆盖渲染已有问题与创建新问题两种使用场景。本文以 SdkQuestionId.md 为骨架结合InteractiveQuestion、StaticQuestion等组件的 Props 定义与前端源码实现系统讲解该类型的四种取值来源、在 SDK 组件中的实际传参方式以及new与new-native两种新建模式在源码中的处理逻辑帮助你在嵌入应用里正确、灵活地指定要展示的问题。一、类型定义一个联合类型的四种身份SdkQuestionId 的定义非常简洁是一个 TypeScript 联合类型type SdkQuestionId number | new | new-native | SdkEntityId;其中SdkEntityId是 Metabase SDK 定义的品牌字符串branded string类型用于让普通字符串与实体 ID 在类型层面区分开type SdkEntityId string {};从类型结构可以看出一个合法的SdkQuestionId只能是以下四种形态之一取值形态含义来源number问题的数值 ID问题链接 URL如http://localhost:3000/question/1-my-question中的1string实体 ID问题的全局唯一字符串 ID问题对象上的entity_id字段可通过 API 或 SDK 的 Collection Browser 获得new打开 Notebook 编辑器创建新的汇总型notebook-style问题SDK 保留字面量new-native打开 SQL 编辑器创建新的原生 SQL 问题SDK 保留字面量官方示例原文给出了四段覆盖全部取值形态的示例代码// Numerical ID from question URL const questionId: SdkQuestionId 123; // Entity ID string const questionId: SdkQuestionId abc123def456; // Create new notebook-style question const questionId: SdkQuestionId new; // Create new native SQL question const questionId: SdkQuestionId new-native;二、数值 ID从问题 URL 中提取数值 ID 是最直观、最常见的问题标识方式。在 Metabase 中打开任意一个问题时浏览器地址栏的 URL 形如http://localhost:3000/question/1-my-question其中 URL 路径中紧跟/question/的数字1就是该问题的数值 ID后面的my-question只是便于阅读的 slug不参与标识。将questionId设为该数字即可在嵌入组件中渲染这个已保存的问题。在 InteractiveQuestionProps.md 与 StaticQuestionProps.md 中questionId属性的类型均为SdkQuestionId | null其说明原文确认了这种获取方式the numerical ID when accessing a question link, i.e.http://localhost:3000/question/1-my-questionwhere the ID is1三、实体 ID字符串形式的稳定标识除数值 ID 外Metabase 的每个问题还拥有一个全局唯一的字符串实体 IDentity ID。获取它的途径有两种直接调用 Metabase REST API问题对象的响应体中含有entity_id键使用 SDK 的 Collection Browser通过CollectionBrowser组件浏览集合并选择数据时返回的问题数据中同样带有entity_id字段。实体 ID 的好处是与数据库自增主键解耦在跨环境迁移、序列化/反序列化参考仓库中的 serialization.md 所描述的能力等场景下更加稳定。使用时直接将实体 ID 字符串传给questionId即可例如上文的abc123def456。四、新建模式new与new-nativenew与new-native是 SDK 提供的两个特殊字面量用于在嵌入应用中从零开始创建问题分别对应两种编辑器new展示 Notebook 编辑器引导用户通过可视化的步骤选表、汇总、筛选、分组等构建查询问题new-native展示原生 SQL 编辑器让用户直接编写 SQL 查询。当questionId为这两个值之一时SDK 内部会把组件切换到新建问题的工作模式。这一点在源码中有明确的判据见下文源码分析。五、在 SDK 组件中如何使用Props 一览SdkQuestionId并非独立使用的 API而是作为多个公开组件questionId属性的类型。目前仓库中直接引用它的组件 Props 包括InteractiveQuestionProps.md交互式问题组件可编辑、可下钻、可保存questionId?: SdkQuestionId | nullStaticQuestionProps.md静态问题组件轻量只读展示questionId?: SdkQuestionId | nullSdkQuestionProps.md交互式问题组件的基础 Props 类型questionId?: SdkQuestionId | null。一个典型用法是配合InteractiveQuestion渲染一个已保存的问题import { InteractiveQuestion } from metabase/embedding-sdk-react; export function RevenueQuestion() { return InteractiveQuestion questionId{123} /; }而要在嵌入应用内新建问题则只需把questionId换成new或new-native// Notebook 编辑器 InteractiveQuestion questionIdnew / // 原生 SQL 编辑器 InteractiveQuestion questionIdnew-native /与card/query/token的互斥关系在 SdkQuestionEntityPublicProps.md 中可以看到questionId与另外三个属性构成互斥联合discriminated union一次只能提供card、query、questionId、token四者之一其余必须为never。这意味着传questionId时不能再同时传card临时问题定义或query由useMetabaseQueryObject创建的临时查询对象反过来token形态客座嵌入的 JWT 令牌模式则由 SDK 内部解析出资源 ID调用方无需传questionId。这种设计让渲染已保存问题questionId渲染临时问题card/query受令牌约束的问题token三种模式在类型层面就被严格区分避免调用方混淆。六、源码级验证new/new-native是如何被处理的1. InteractiveQuestion 的入口判断在 InteractiveQuestion.tsx 中InteractiveQuestionInner会对questionId做归一化处理当通过query属性渲染例如 Metabot 的navigate_to跳转时没有传入questionId此时会从反序列化后的 card 中推导出问题 ID以保证原生查询能打开 SQL 编辑器。随后组件用如下代码判定是否处于新建模式const isNewQuestion resolvedQuestionId new || resolvedQuestionId new-native;该布尔值进一步用于 SDK 组件挂载埋点useTrackSdkComponentMount区分id_new与id_new_native两种埋点场景说明 SDK 在分析侧也将两种新建模式分开统计。2. SdkQuestionProvider 的上下文处理在 SdkQuestionProvider.tsx 中传入的原始questionId会先经过useExtractResourceIdFromJwtToken处理const { resourceId: questionId, token, tokenError, } useExtractResourceIdFromJwtToken({ isGuestEmbed, resourceId: rawQuestionId, ... });即在客座嵌入guest embed场景下若传入了 JWT 令牌问题资源 ID 会从令牌中提取否则直接使用调用方传入的rawQuestionId。提取之后同一套判据再次出现const isNewQuestion questionId new || questionId new-native;后续的创建问题useCreateQuestion、保存问题useSaveQuestion等内部 hooks 都会依据这个标志走新建流程从而让questionIdnew/new-native真正打开对应的编辑器并支持把新问题保存回 Metabase。从上述两处源码可以看出new与new-native不是 UI 层的魔法字符串而是贯穿组件挂载、埋点、资源解析与创建/保存流程的核心分支条件。七、实践建议与注意事项两种 ID 的取舍临时嵌入、ID 不会跨环境迁移时直接使用 URL 中的数值 ID 最简单需要长期稳定引用、或通过 API/Collection Browser 获取数据时优先使用entity_id字符串。新建模式与保存能力配合使用new/new-native进入新建模式后建议配合isSaveEnabled控制是否显示保存按钮与targetCollection保存目标集合等 Props 一起使用才能形成新建 → 编辑 → 保存的完整闭环相关属性说明见 SdkQuestionProps.md。不要混用互斥属性questionId与card、query互斥同时传入会被 TypeScript 的联合类型直接拦截这也是SdkQuestionEntityPublicProps将对应字段声明为never的原因。客座嵌入注意在通过tokenJWT 客座嵌入渲染问题时资源 ID 由令牌决定通常不需要再显式传questionId。八、相关 API 索引SdkQuestionId 属于 Embedding SDK 公开 API 类型体系的一部分。在 API 索引 中与它直接相关的类型与组件包括SdkEntityId实体 ID 的品牌字符串类型SdkQuestionEntityPublicPropsquestionId/card/query/token互斥联合InteractiveQuestionProps 与 StaticQuestionProps消费SdkQuestionId的组件 PropsSdkQuestionProps交互式问题组件完整 Props前端实现参考InteractiveQuestion.tsx、SdkQuestionProvider.tsx。理解SdkQuestionId的四种形态是正确使用InteractiveQuestion、StaticQuestion等 SDK 问题组件的第一步——无论是展示已有分析、还是把新建问题的能力直接嵌入到你的产品中。【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考