Shopifyの在庫更新をPythonとGraphQLを使ってやってみよう。ShopfiyのAPIにはRESTとGraphQLの2種類のリクエスト方法があるが、両者を比較すると明らかにGraphQLのほうが軽量で扱いやすい。
というのも、RESTの場合、例えば在庫を取得するにしても在庫以外の余計な情報が返ってくる。これはつまりプログラムで余計なメモリを消費することを意味するわけで、明らかにGraphQLのほうがメリットが大きいだろう。
とくに商品数が数万点におよぶなどの場合にGraphQLの恩恵をより感じられるだろう。よほどの事情がない限りShopifyのAPIはGraphQLでリクエストすることを勧める。
在庫更新にはいくつか方法があるが、今回はinventorySetOnHandQuantitiesで更新する方法を紹介する。ShopifyのAPIの認証に必要なのはtokenとshopのurlだが、tokenはすでに発行されているものとする。
inventory_item_idを取得するPythonのコード
Shopifyの場合skuだけで更新できないのが楽天などの他のモールAPIとの違いだろう。skuを軸にして、inventory_item_idを照会しないとならない。また、現時点でShopifyのAPIの一度のリクエストの上限は250なので、その点にも留意する必要がある。ページネーションで次の情報がある場合は、RESTならレスポンスのheaderに情報が含まれているし、GraphQLならレスポンスのなかにhasNextPageという項目があり、ある場合はTrueとある。また、nextPageCursorに必要な情報が格納されている。
import requests import json url = '/admin/api/2023-01/graphql.json' #graphQLのエンドポイント shop_url = 'https://hogehoge.myshopify.com' #利用環境に準ずる token = 'hogehoge' #利用環境に準ずる cursor = '' #pagenationの値 limit = 250 #一度のリクエスト上限 headers = { 'Content-Type': 'application/json', 'X-Shopify-Access-Token': token, } data = '{ inventoryItems(first: ' + str(limit) + ',' if cursor != None: data += 'after: ' + '"' + cursor + '"' data += ''') { edges { #cursor node { id sku } } pageInfo{ hasNextPage endCursor } } }''' url = shop_url + url response = requests.post(url, headers=headers, json={'query': data}) if response.status_code == 200: json_data = json.loads(response.text)
これは一度のリクエストをするだけなので、取り扱い商品数が250点以上の場合は、必要に応じて繰り返し処理をする。レスポンスのなかにskuとinventory_item_idがある。これでskuを元に関連付けができる。
在庫を更新する
在庫更新に必要なのは以下の情報だ。
- sku
- inventory_item_id
- location_id
location_idはどの店舗のidであるかを示すIDを指す。運営している店舗が1店舗なら1つしかないし、複数ならその数の分だけある。つまりShopifyの在庫に関する仕様は、店舗ごとに個別の在庫を持てるということだ。当たり前といえば当たり前なのだが、この仕様のおかげでAPIの仕様がやや複雑になっている。
#更新したい商品の情報を配列に格納する items_inventory_info = [{'quantity': 80, 'inventory_item_id': str, 'locationId': location_id}] location_id = 'hogehoge' #利用環境に準ずる headers = { 'Content-Type': 'application/json', 'X-Shopify-Access-Token': token, } query = ''' mutation inventorySetOnHandQuantities($input: InventorySetOnHandQuantitiesInput!) { inventorySetOnHandQuantities(input: $input) { userErrors { field message } inventoryAdjustmentGroup { createdAt reason changes { name delta } } } } ''' url = '/admin/api/2023-01/graphql.json' #graphQLのエンドポイント url = shop_url + url variables = dict({ "input": { "reason": "correction", "setQuantities": items_inventory_info } } ) res = requests.post(url, headers=headers, json={'query': query, 'variables': variables}) response.append(res)
以上でShopify店舗の在庫更新ができる。