Shopify の GraphQL API にあるProducts
クエリを使えば、商品データを複数取得することが出来ます。しかし、このクエリはfirst: 10
のように「最初から10個までを取得する」といった数の指定が必須です。
ページのカウント数から残りの取得数を割り出すこともできますが、Shopify ではbulkOperation
なるものを使うと、一度のリクエストで全データをまとめて取得できます。
https://shopify.dev/tutorials/perform-bulk-operations-with-admin-api
Product に限らず好きな query を実行できますが、ここでは Product のデータをまとめて取得しようと思います。
クエリの確認は Insomnia や Postman などのリクエストアプリを使うとやりやすいです。
取得の流れ
最初に貼ったURLを参考にすれば動きますが、流れとしては
bulkOperationRunQuery
の mutation を実行(引数に取得のためのquery
を書く)- クエリが実行され、実行中のクエリidが返ってくる
currentBulkOperation
クエリを投げ、status
がCOMPLETED
になるまで一定の間隔で投げ続けるurl
にクエリの結果がjsonl
形式で出力されているのでダウンロードする
になります。簡単に説明すると
取得したいデータがあるので、shopifyにクエリの実行をお願いする
↓
shopify が頑張る
↓
「終わった?」という確認を(3)で終わるまで続ける
↓
終わったらダウンロードURLが発行されるので、アクセスする
と、少し手間のかかる作業が必要になります。
bulkOperationRunQuery でクエリを実行してもらう
まずは普通にクエリを書きます。
例:product_status
がactive
の商品情報を全件取得
本来、引数にfirst
やend
が必須ですが不要です。
productVariants(query: "product_status:active") {
edges {
node {
product {
id
title
}
price
inventoryQuantity
}
}
}
ではこのクエリを、mutation
に組み込みます。query
の引数に先ほどのクエリを入れるのですが、ダブルクォーテーション三つで囲む必要があるようです。さらにその直下は{}
でラップします。
mutation {
bulkOperationRunQuery (
query: """
{
productVariants(query: "product_status:active") {
edges {
node {
product {
id
title
}
price
inventoryQuantity
}
}
}
}
"""
) {
bulkOperation {
id
status
}
userErrors {
field
message
}
}
}
(なんでダブルクォーテーション3つが必要なのかよく分かりません…)
ちなみに variables に引数を設定しようと思ったんですが、このダブルクォーテーションのせいなのか上手くいかなかったので、直接埋め込んでいます。variables は json 形式なので、一行ずつダブルクォーテーションで囲めばいけるのかもしれませんが、それだと結局見にくいのであまり意味はなさそう。
特にエラーなどが無ければ成功です。
currentBulkOperation で実行ステータスを確認する
これでクエリを実行してもらいましたが、終わったかどうかはこちらから逐一確認しないと教えてくれません。時間を置いてクエリを投げてみます。
(データが多い場合はすぐに確認しても実行中である可能性が高いです)
query {
currentBulkOperation {
id
status
errorCode
createdAt
completedAt
objectCount
fileSize
url
partialDataUrl
}
}
status
がCOMPLETED
になるまで確認し続けます。何かしらのプログラムでたたいているなら、適当な時間を設定して自動でクエリを投げるとよいかもしれません。結果を単にダウンロードして保存したいだけなら、時間を置いて投げてみてください。
ちなみに、currentBulkOperation は最新の bulkOperation の結果を表示しますが、複数の bulkOperation を同時に実行することもできるため混在することもあります。特定の実行ステータスを確認したい時は、id
を指定すればよいみたいです。
{
node(id: "bulkOperationRunQueryのID") {
... on BulkOperation {
id
status
url
}
}
}
ファイルをダウンロードする
終わると、url
に長ったらしいURLが入っているのでアクセスすると自動的にファイルがダウンロードされます。
node.js などでファイルを直接読みこむ場合は、fetch
などを使ってファイルを読み込んでから解析する必要がありますが、それはまたいずれ書きます。