フィールド単位のトリガー/自前 GraphQL クエリで定義する payload/何が変わったかを示す fields_changed。Webhook の「ノイズ問題」と「追加 API 呼び出し問題」を同時に解決する次世代の仕組み。
product/update が title・tag・price のどれで起きたか分からない。固定スキーマで送られ、欲しい項目は別途 GraphQL で取り直す。
triggers でフィールドを宣言。query で payload を定義。query_filter で現在状態を絞る。fields_changed で何が変わったか明示。
product.variants.price を購読すれば、title や tag が変わっても発火しない。価格が変わった時だけ飛んでくる。
標準の Admin GraphQL クエリで 欲しい形・欲しい項目だけ を指定。固定スキーマに縛られず、配信後に追加 API を叩く必要も無い。
各配信に 変更されたフィールドの完全パスと ID が含まれる。前回値との diff 計算や状態の推測が不要になる。
クエリ結果の 現在の状態 に基づいて配信可否を決定。例 : product.status:'ACTIVE' で公開中の商品変更だけ受け取る。
| 項目 | 従来 Webhook | Next Generation Events |
|---|---|---|
| 発火粒度 | トピック単位 product/update 全部 | フィールド単位 variants.price だけ等 |
| ペイロード形状 | 固定スキーマ | 自前 GraphQL で定義 |
| 追加 API 呼び出し | 必要(欲しい項目を取りに行く) | 不要 |
| 何が変わったか | 受け手が diff 計算 | fields_changed に明示 |
| 現在状態での絞り込み | 受信後に自前で判定 | query_filter で事前絞り |
| 設定の置き場所 | 管理画面 / API | shopify.app.toml(Git 管理) |
| 提供状態 | GA | developer preview / unstable |
価格変更だけを購読し、自前の GraphQL で必要項目を取得、公開中の商品に絞る例。
[events] api_version = "unstable" [[events.subscription]] handle = "price_sync" topic = "Product" actions = ["update"] triggers = [ "product.variants.price", "product.variants.compareAtPrice" ] uri = "/api/events" query = """ query priceSync($productId: ID!, $variantsId: ID!) { productVariant(id: $variantsId) { id price compareAtPrice sku } product(id: $productId) { id title status } } """ query_filter = "product.status:'ACTIVE'"
{
"topic": "Product",
"action": "update",
"handle": "price_sync",
"data": {
"productVariant": {
"id": "gid://shopify/ProductVariant/456",
"price": "24.99",
"compareAtPrice": "34.99",
"sku": "SIGNAL-NOT-NOISE"
},
"product": {
"id": "gid://shopify/Product/123",
"title": "Peace & Quiet Tee",
"status": "ACTIVE"
}
},
"fields_changed": [
"product[id: 'gid://shopify/Product/123'].variants[id: 'gid://shopify/ProductVariant/456'].price"
],
"query_variables": {
"productId": "gid://shopify/Product/123",
"variantsId": "gid://shopify/ProductVariant/456"
}
}
自分で定義したクエリの戻り値が入る。追加で API を叩く必要は無い。
完全パスと ID で表現。...variants[id: ...].price の形。
どの ID で取りに行ったかが明示。冪等処理やログ突合に有用。
developer preview なので API バージョンは unstable 固定。本番投入前にバージョン更新時の影響範囲を CI で検知できる仕組みが必要。
記事時点で Product と Customer のみ稼働。Order・Inventory 等は記載なし → 既存 Webhook の置換は段階的にしか進められない。
shopify.app.toml に handle/topic/triggers/uri/query/query_filter が全部入る。レビュー・差分・ロールバックが Git で完結。
配列要素を variants[id: 'gid://...'].price で表す独自構文。パーサを書くか、文字列マッチで分岐する設計を最初に決めておくべき。
triggers =「何が変わったか」での絞り込み(事前条件)。query_filter =「現在の状態」での絞り込み(事後条件)。
例 : 「価格が変わった & 現時点で公開中」のように、両者を組み合わせると Webhook 設計が宣言的に綺麗にまとまる。
product.variants.price と compareAtPrice だけ宣言。query に SKU・価格のみ含める。query_filter で status:'ACTIVE' に絞る。