Metabase Embedding SDK 的 SdkDashboardId 类型:数值 ID、字符串 entity_id 与类型安全的仪表板标识

Metabase Embedding SDK 的 SdkDashboardId 类型:数值 ID、字符串 entity_id 与类型安全的仪表板标识 Metabase Embedding SDK 的 SdkDashboardId 类型数值 ID、字符串 entity_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/metabaseSdkDashboardId是 Metabase Embedding SDK模块化嵌入中用于标识仪表板的统一类型它以联合类型的形式同时接纳「URL 中的数值 ID」与「API 返回的字符串 entity_id」两种形态。本文将以该类型定义为骨架结合SdkDashboard组件、SdkDashboardEntityPublicProps等公开类型及frontend/src/embedding-sdk-bundle下的真实实现讲解它的定义、获取方式、使用位置与底层解析逻辑帮助你写出类型安全、不会因 ID 形态混淆而出错的嵌入式仪表板代码。类型定义一个联合类型三种形态在 docs/embedding/sdk/api/snippets/SdkDashboardId.md 中该类型的定义只有一行type SdkDashboardId number | string | SdkEntityId;它不是一个普通的新类型而是三个可接受形态的联合union形态类型含义典型来源数值 IDnumber仪表板在 Metabase 数据库中的自增主键仪表板访问链接中的数字段普通字符串string以字符串形式承载的任意标识通过 API 或 Collection Browser 拿到的entity_id实体 IDSdkEntityId一种带品牌标记的字符串类型专门表示 Metabase 的实体标识符API 响应中 dashboard 对象的entity_id字段从类型系统的角度看number | string已经足够宽松第三项SdkEntityId的加入并不是功能上的硬性要求而是为类型层面的可读性与约束服务的——它让这是 entity_id 字符串这一语义在编译期就可见。SdkEntityId一种被标记的字符串类型SdkEntityId同样定义在 SDK 的类型目录中见 docs/embedding/sdk/api/snippets/SdkEntityId.mdtype SdkEntityId string {};这是 TypeScript 中经典的品牌类型branded type写法string {}在运行时没有任何额外结构{}的作用纯粹是为了让SdkEntityId与普通string在类型层面区分开。这样设计的好处是运行时零开销它就是一个字符串可以直接传给 API、URL 或存储语义可区分当一个函数声明参数为SdkEntityId调用方就清楚这里应当传入 entity_id 而非其他任意字符串赋值仍然兼容SdkEntityId可以赋给string类型的变量反之则需要显式断言从而在编译期拦截把普通字符串误当 entity_id的用法。对应的源码声明位于 frontend/src/embedding-sdk-bundle/types/entity.tsexport type SdkEntityId string {}; export type SdkEntityToken string;如何获取仪表板的 ID两条来源路径SdkDashboardEntityPublicProps的文档见 docs/embedding/sdk/api/snippets/SdkDashboardEntityPublicProps.md明确说明了dashboardId的两种合法来源数值 ID当你访问仪表板链接时URL 形如http://localhost:3000/dashboard/1-my-dashboard其中的数字1就是数值 ID。字符串 entity_id当你直接使用 Metabase API或使用 SDK 的 Collection Browser 选择仪表板时数据对象中的entity_id字段就是字符串形式的 ID。在 API 返回的MetabaseDashboard实体类型中两种 ID 会同时存在定义见 frontend/src/embedding-sdk-bundle/types/dashboard.tsexport type MetabaseDashboard { id: SdkDashboardId; // 数值 ID或字符串 entity_id entity_id: SdkEntityId; // 字符串实体 ID created_at: string; updated_at: string; collection?: MetabaseCollection | null; name: string; description: string | null; last-edit-info: { id: number; email: string; first_name: string; last_name: string; timestamp: string; }; };其中id字段直接声明为SdkDashboardIdentity_id字段声明为SdkEntityId与类型定义一一对应。SdkDashboardId 在 SDK 中的核心使用位置1. SdkDashboard 组件的dashboardId属性SdkDashboard以及基于它的InteractiveDashboard、EditableDashboard是模块化嵌入中最常用的仪表板组件。它的dashboardIdprop 类型就是SdkDashboardId见 frontend/src/embedding-sdk-bundle/components/public/dashboard/SdkDashboard.tsxexport type SdkDashboardProps PropsWithChildren { // ... /** * The ID of the dashboard. * This is either: * - the numerical ID when accessing a dashboard link, * i.e. http://localhost:3000/dashboard/1-my-dashboard where the ID is 1 * - the string ID found in the entity_id key of the dashboard object * when using the API directly or using the SDK Collection Browser */ dashboardId: SdkDashboardId; // ... } // ... ;实际使用时两种写法都合法// 方式一数值 ID从仪表板 URL 中提取 SdkDashboard dashboardId{1} / // 方式二字符串 entity_id从 API 或 Collection Browser 获取 SdkDashboard dashboardIdG3gHfP_4hOG8k6JwQmXvzA /2. SdkDashboardEntityPublicPropsdashboardId 与 guest token 的二选一在SdkDashboardEntityPublicProps中SdkDashboardId与SdkEntityTokenguest 嵌入的 JWT token构成互斥关系——要么通过dashboardId指定仪表板要么通过token走 guest 嵌入二者不可同时出现见 frontend/src/embedding-sdk-bundle/types/dashboard.tsexport type SdkDashboardEntityPublicProps | { dashboardId: SdkDashboardId | null; token?: never; } | { dashboardId?: never; token: SdkEntityToken | null; };这一设计用 TypeScript 的 discriminated union 在编译期就杜绝了同时传入两个标识的歧义当选择dashboardId分支时token被约束为never选择token分支时dashboardId被约束为never。3. 内部统一处理useSdkDashboardParams 与 JWT 解析在 SDK 内部dashboardId并不总是直接作为请求参数使用。SdkDashboard组件的内部实现中首先通过useExtractResourceIdFromJwtToken判断当前是否为 guest 嵌入若是则从 JWT token 中提取资源 ID否则直接使用传入的dashboardId见 SdkDashboard.tsxconst { resourceId: dashboardId, token, tokenError, } useExtractResourceIdFromJwtToken({ isGuestEmbed, resourceId: rawDashboardId, token: (!isFirstRender ? tokenFromStore : null) ?? rawToken ?? undefined, });也就是说SdkDashboardId在内部会被解析为真正用于加载数据的resourceId这一层对使用者完全透明。4. 无效 ID 的错误处理对于无效的 IDSDK 有明确的兜底逻辑。在 SdkDashboard.tsx 中404仪表板不存在与 400entity_id 格式非法都会被识别为仪表板未找到渲染DashboardNotFoundError// Passing an invalid entity ID format results in a 400 Bad Request. // We can show this as a generic not found error on the frontend. const isDashboardNotFound errorPage?.status 404 || errorPage?.status 400; if (!dashboardId || isDashboardNotFound) { return ( DashboardNotFoundError id{dashboardId ?? } / ); }这一实现提醒我们传入格式非法的 entity_id 会得到 400 而不是 404二者在 SDK 中被统一处理为未找到。与 SdkQuestionId 的对比仪表板没有新建特殊值同为实体标识类型SdkQuestionId 比SdkDashboardId多出两个特殊字符串值type SdkQuestionId number | new | new-native | SdkEntityId;SdkQuestionId中的new与new-native分别代表新建 notebook 式问题与新建原生 SQL 问题用于让InteractiveQuestion组件进入创建模式。而SdkDashboardId没有对应的特殊值——仪表板组件总是渲染一个已存在的仪表板新建仪表板需要通过useCreateDashboardApi钩子创建完成后会返回新仪表板的 ID随后即可将其作为SdkDashboardId传入组件。从源码可以印证在SdkDashboard的 query builder 流程中新建问题使用的是questionIdnew见 SdkDashboard.tsx而仪表板 ID 始终来自dashboard.id不存在new这类占位值。实践建议何时用数值 ID何时用 entity_id结合类型定义与使用场景可以给出以下实践指引链接跳转 / 深链接场景如果嵌入应用需要根据 URL 路由还原仪表板从/dashboard/{id}-{slug}中解析出的数值 ID 直接就是合法的SdkDashboardId无需转换。API / Collection Browser 场景当仪表板数据来自 API 响应或用户在 Collection Browser 中选中时优先使用entity_id。entity_id 是跨环境稳定的业务标识不随数据库重建或迁移而改变更适合持久化存储。类型安全定义自己的组件 props 时尽量显式声明为SdkDashboardId这样调用方传入任何合法形态都能通过编译检查如果需要明确语义比如只接受 entity_id则可以进一步使用SdkEntityId。错误兜底由于非法 entity_id 会触发 400 错误SDK 会将其当作仪表板未找到处理建议在持久化 entity_id 时先校验其格式或在组件外层监听加载错误回调onLoad/onLoadWithoutCards定义见 dashboard.ts做统一的降级 UI。总结SdkDashboardId虽然只是一个三行联合类型却是整个 Embedding SDK 仪表板能力的入口类型它统一了数值 ID 与字符串 entity_id 两种形态通过SdkEntityId的品牌类型为字符串标识提供类型级语义约束并贯穿于SdkDashboardProps、SdkDashboardEntityPublicProps、MetabaseDashboard实体与 guest 嵌入的 JWT 解析链路中。理解它的定义与解析路径就能在嵌入开发中正确选择 ID 来源、规避 400/404 错误并写出更健壮的类型安全代码。【免费下载链接】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),仅供参考