元字段
Metafields API 用于在前台 JavaScript 中读取元字段,补上 Liquid 做不到的部分:Liquid 在页面渲染时取值,而且只能取当前页面已有的对象,例如商品页上的 product.metafields。这两个 endpoint 在浏览器里任意时刻都能调,按对象 id 取值,因此可以读任意商品、专辑或店铺自身的元字段——页面加载完之后读、在拿不到 Liquid 上下文的脚本里读,或者一次请求读多个对象。
元字段是什么、怎么定义,见元字段概述;Liquid 侧的读法见在 Liquid 中使用元字段。
两个 endpoint 匿名访客都可以调用。
所有 Ajax API 请求应使用多语言 URL,以便为访客提供一致的体验。
按对象类型读取元字段列表
GET /{locale}/api/front/metafields/{owner_resource}/list
以平铺列表的形式读取某一类对象的元字段。owner_resource 取 shop、product、product_variant 或 collection。
返回什么由两件事决定:owner_ids 传几个,以及是否用 namespace 和 key 指定字段:
| 想读什么 | owner_ids | namespace + key |
|---|---|---|
| 一条元字段 | 传一个 id | 传一对 |
| 一个对象的全部元字段 | 传一个 id | 不传 |
| 多个对象的同一个字段 | 每个 id 重复传一次 | 传一对 |
| 多个对象的全部元字段 | 每个 id 重复传一次 | 不传 |
limit 和 page 只负责翻页,不影响选出哪些元字段。
请求示例
const params = new URLSearchParams({
namespace: 'custom',
key: 'manual_test',
limit: '10'
});
params.append('owner_ids', '14a309ec-b966-4cf9-a9bb-33baa821fdbc');
params.append('owner_ids', 'f934ce3e-02c2-4e97-8412-19221eedbffd');
fetch(window.SHOPLAZZA.routes.root + '/api/front/metafields/product/list?' + params)
.then((response) => response.json())
.then((data) => {
// do something...
});
请求参数
对象类型:shop、product、product_variant 或 collection。
要读取的对象 id。重复传该参数可一次读多个对象。shop 时传店铺 id。
只返回该命名空间下的元字段。
只返回该 key 的元字段,与 namespace 一起使用。
只返回由该元字段定义创建的元字段。与批量查询接口 definition_ids 用的是同一种 id。
返回的元字段条数。
返回第几页元字段,从 1 开始,传 0 按 1 处理。
响应
total、remain、page、total_page、have_next 在返回了元字段时也保持为 0 或 false。
- 数据结构
- 示例
- Array [
- ]
data object
响应数据主体。
metafields object[]
元字段列表。
元字段的 ID。
对象所属店铺的 ID。
元字段所属资源的 ID。
元字段所属的资源类型,例如 product。
元字段所属的命名空间。
元字段的键名,在命名空间内唯一。
元字段的值,数据类型由 type 决定。
元字段的值类型,例如 single_line_text_field。
元字段的描述。
创建时间(ISO-8601 格式)。
最后更新时间(ISO-8601 格式)。
匹配到的元字段总数。
当前页码。
总页数。
是否还有下一页。
响应返回的结果说明。
请求结果标识,success 或 0 表示请求成功。
{
"data": {
"metafields": [
{
"id": "676328500579297095",
"store_id": 2446407,
"owner_id": "14a309ec-b966-4cf9-a9bb-33baa821fdbc",
"owner_resource": "product",
"namespace": "custom",
"key": "manual_test",
"value": "222222222",
"type": "single_line_text_field",
"description": "",
"created_at": "2026-08-10T07:28:25Z",
"updated_at": "2026-08-10T07:28:25Z"
},
{
"id": "686766315775468871",
"store_id": 2446407,
"owner_id": "f934ce3e-02c2-4e97-8412-19221eedbffd",
"owner_resource": "product",
"namespace": "custom",
"key": "manual_test",
"value": "333333333",
"type": "single_line_text_field",
"description": "",
"created_at": "2026-09-08T02:44:09Z",
"updated_at": "2026-09-08T02:44:09Z"
}
],
"total": 0,
"remain": 0,
"page": 0,
"total_page": 0,
"have_next": false
},
"msg": "请求成功",
"state": 0
}
前台没有按元字段 id 取单条的 endpoint。要读取任意对象的某一条元字段,调用本 endpoint,路径里放该对象的 owner_resource,owner_ids 只传一个对象 id,再加上这条元字段的 namespace 和 key,data.metafields 里就只有这一条。对比上面的请求示例:那里传了两个 owner_ids,读的是两个商品的同一个字段。这里读的是一个商品的一条元字段,其他对象把路径里的 product 换成 shop、product_variant 或 collection 即可:
const params = new URLSearchParams({
owner_ids: '14a309ec-b966-4cf9-a9bb-33baa821fdbc',
namespace: 'custom',
key: 'manual_test'
});
fetch(window.SHOPLAZZA.routes.root + '/api/front/metafields/product/list?' + params)
.then((response) => response.json())
.then((data) => {
const metafield = data.data.metafields[0];
console.log(metafield ? metafield.value : 'not set');
});
下面的批量 endpoint 在 unique_keys 只传一对 namespace 和 key 时效果相同。前台不能新建或修改元字段,这类操作走 Metafield REST API。
批量按对象查询元字段
POST /{locale}/api/front/v2/metafields/{owner_resource}/query
一次请求读取多个对象的元字段,并按对象分组返回。owner_resource 支持 shop、product 和 collection;传其他取值会返回 422,响应体为 {"errors":["unsupported owner_resource"]}。
筛选元字段有两种方式:用 unique_keys 按命名空间和 key 筛,或用 definition_ids 按定义筛。两者必须且只能传一个:都不传或都传都会返回 422,响应体为 {"errors":["exactly one of unique_keys or definition_ids is required"]}。
owner_resource 为 shop 时可以不传 owner_ids,因为店铺是唯一可能的 owner。
请求示例
const data = {
owner_ids: ['14a309ec-b966-4cf9-a9bb-33baa821fdbc'],
unique_keys: [
{ namespace: 'custom', key: 'manual_test' }
]
};
fetch(window.SHOPLAZZA.routes.root + '/api/front/v2/metafields/product/query', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then((response) => response.json())
.then((data) => {
// do something...
});
请求参数
- 数据结构
- 示例
- Array [
- ]
对象类型:shop、product 或 collection。
要读取的对象 id 列表。owner_resource 为 shop 时可省略。
unique_keys object[]
要读取的元字段,每项是带 namespace 和 key 的对象。
要读取的元字段定义 id 列表。与 unique_keys 二选一,不能同时传。
{
"owner_ids": [
"14a309ec-b966-4cf9-a9bb-33baa821fdbc"
],
"unique_keys": [
{
"namespace": "custom",
"key": "manual_test"
}
]
}
响应
- 数据结构
- 示例
- Array [
- Array [
- ]
- ]
data object
响应数据主体。
owner_metafields object[]
按所属资源分组的元字段。
元字段所属资源的 ID。
metafields object[]
元字段列表。
元字段的 ID。
对象所属店铺的 ID。
元字段所属资源的 ID。
元字段所属的资源类型,例如 product。
元字段所属的命名空间。
元字段的键名,在命名空间内唯一。
元字段的值,数据类型由 type 决定。
元字段的值类型,例如 single_line_text_field。
元字段的描述。
创建时间(ISO-8601 格式)。
最后更新时间(ISO-8601 格式)。
元字段关联的定义 ID。
响应返回的结果说明。
请求结果标识,success 或 0 表示请求成功。
{
"data": {
"owner_metafields": [
{
"owner_id": "14a309ec-b966-4cf9-a9bb-33baa821fdbc",
"metafields": [
{
"id": "676328500579297095",
"store_id": 2446407,
"owner_id": "14a309ec-b966-4cf9-a9bb-33baa821fdbc",
"owner_resource": "product",
"namespace": "custom",
"key": "manual_test",
"value": "222222222",
"type": "single_line_text_field",
"description": "",
"created_at": "2026-08-10T07:28:25Z",
"updated_at": "2026-08-10T07:28:25Z",
"definition_id": "676319747943433287"
}
]
}
]
},
"msg": "请求成功",
"state": 0
}