Shopify API の使い方について徹底解説

株式会社リテリアのアイコン
株式会社リテリア

記事の画像は、公式ドキュメント内の画像を引用しております。

公式ドキュメント

目次

Shopify API のアクセススコープについて

アプリケーションが Shopify のショップにアクセスする際には、特定のアクセス権限を要求する必要があります。これらのアクセス権限は「アクセススコープ」と呼ばれ、Shopify の認証済みアクセススコープまたは未認証アクセススコープから選択できます。

アプリケーションがどのアクセススコープを持っているかは、Shopify の Admin API を通じて提供される AccessScope リソースを使って確認できます。これは、GraphQL と REST の両方の Admin API で利用可能です。

要するに、アプリケーションが Shopify ショップのどの部分にアクセスできるかは、要求されるアクセススコープによって決定され、これらのスコープは Shopify の Admin API を介して管理および確認できます。

認証されたアクセススコープについて

認証されたアクセススコープは、Shopify の REST Admin API と GraphQL Admin API を通じて、どのリソースにアプリケーションがアクセスできるかを制御します。これらのアクセス権限を持つアプリケーションは、Shopify ストアのオーナー(マーチャント)に代わって様々な操作を行うことができます。たとえば、新しい商品を作成したり、割引コードを管理するなどのアクションを実行することが可能です。

簡単に言うと、認証されたアクセススコープは、アプリケーションが Shopify の管理 API を通じてストアの特定の部分とやり取りするためのアクセス許可を定義します。これにより、ストアの管理や更新などの重要な機能を実行できるようになります。

  • read_content,write_content
    ArticleBlogCommentPageRedirectにアクセスできます。
  • read_themes, write_themes
    AssetThemeにアクセスできます。
  • read_products, write_products
    ProductProduct VariantProduct ImageCollectCustom CollectionSmart Collectionにアクセスできます。
  • read_product_listings
    Product ListingCollection Listingにアクセスできます。
  • read_customers, write_customers
    CustomerSaved Searchにアクセスできます。
  • read_orders, write_orders
    Abandoned checkoutsCustomerFulfillmentOrderTransactionにアクセスできます。
  • read_all_orders
    60 日分の注文のデフォルトウィンドウではなく、全ての注文へのアクセスを許可します。この OAuth スコープは、read_ordersまたはwrite_ordersと組み合わせて使用されます。このスコープをアプリケーションに追加する前に、Partner Dashboard からこのスコープをリクエストする必要があります。
  • write_order_edits
    GraphQL Admin API のorder editing機能にアクセスできます。
  • read_draft_orders, write_draft_orders
    Draft Orderにアクセスできます。
  • read_inventory, write_inventory
    Inventory LevelInventory Itemにアクセスできます。
  • read_locations
    Locationにアクセスできます。
  • read_script_tags, write_script_tags
    Script Tagにアクセスできます。
  • read_fulfillments, write_fulfillments
    Fulfillment Serviceにアクセスできます。
  • read_assigned_fulfillment_orders, write_assigned_fulfillment_orders
    fulfillment serviceによって管理された場所に割り当てられたFulfillmentOrderリソースへのアクセスができます。
  • read_merchant_managed_fulfillment_orders, write_merchant_managed_fulfillment_orders
    マーチャントが管理する場所に割り当てられたFulfillmentOrderリソースにアクセスできます。
  • read_third_party_fulfillment_orders, write_third_party_fulfillment_orders
    fulfillment serviceによって管理される場所に割り当てられたFulfillmentOrderリソースへのアクセスができます。
  • read_shipping, write_shipping
    Carrier ServiceCountryProvinceにアクセスできます。
  • read_gift_cards, write_gift_cards
    Gift Cardにアクセスできます。(SHOPIFY PLUN の場合)
  • read_users, write_users
    Userにアクセスできます。(SHOPIFY PLUN の場合)
  • read_checkouts, write_checkouts
    Checkoutsにアクセスできます。
  • read_reports, write_reports
    Reportsにアクセスできます。
  • read_price_rules, write_price_rules
    Price Rulesにアクセスできます。
  • read_discounts, write_discounts
    GraphQL Admin API のDiscounts features.にアクセスできます。
  • read_marketing_events, write_marketing_events
    Marketing Eventにアクセスできます。
  • read_resource_feedbacks, write_resource_feedbacks
    ResourceFeedbackにアクセスできます。
  • read_shopify_payments_payouts
    Shopify Payments のPayoutBalanceTransactionにアクセスできます。
  • read_shopify_payments_disputes
    Shopify Payments のDisputeリソースへのアクセスができます。
  • read_translations, write_translations
    Translatable Resourceにアクセスできます。
  • read_locales, write_locales
    Shop Localeにアクセスできます。

認証されていないアクセススコープについて

認証されていないアクセススコープは、Shopify の Storefront API を通じて、カスタマーに代わってストアの特定の情報にアクセスする権限を定義します。これにより、アプリケーションは商品の表示やチェックアウトプロセスの開始など、カスタマー関連のアクションを行うことができます。

Storefront API にアクセスするためには、専用の「Storefront API トークン」が必要です。これは、Admin API アクセストークンとは異なるものです。

プライベートアプリケーションの場合、Storefront API アクセスを有効にした後、プライベートアプリケーションのセットアップページから直接アクセストークンを取得できます。一方、パブリックアプリケーションやカスタムアプリケーションでは、アプリがインストールされた後、Admin API を使用して Storefront Access Token REST リソースや Storefront Access Token Create GraphQL ミューテーションを通じてトークンを生成します。生成されたトークンは、そのアプリケーションに付与された認証されていないアクセススコープを自動的に引き継ぎます。

簡単に言うと、認証されていないアクセススコープは、カスタマーの代わりにストアの基本的な情報にアクセスし、商品の閲覧や購入プロセスをサポートするためのものです。これらのスコープは Storefront API トークンを通じて管理されます。

  • unauthenticated_read_product_listings
    ProductCollectionオブジェクトの読み取りに認証されていないアクセスができます。
  • unauthenticated_read_product_tags
    Productオブジェクトのtagsフィールドの読み取りに認証されていないアクセスができます。
  • unauthenticated_write_checkouts,unauthenticated_read_checkouts
    Checkoutオブジェクトに認証されていないアクセスができます。
  • unauthenticated_write_customers,unauthenticated_read_customers
    Customerオブジェクトに認証されていないアクセスができます。
  • unauthenticated_read_customer_tags
    Customer オブジェクトのtagsフィールドの読み取りに認証されていないアクセスができます。
  • unauthenticated_read_content
    ArticleBlogCommentオブジェクトなどの storefront content の読み取りに認証されていないアクセスができます。

Shopify API authentication | Shopify の API 認証について

Shopify プラットフォームでは、トランザクションを安全に行うために、API に接続するすべてのアプリケーションは API 呼び出し時に認証を必要とします。つまり、アプリケーションが Shopify のデータにアクセスする際は、特定の認証手順を経る必要があります。

しかし、Storefront API のような一部のリソースでは、認証されていないエンドユーザーでもストアの限られたデータにアクセスすることが許可されています。これにより、ユーザーはログインせずとも、商品の閲覧などの基本的な機能を利用できます。

簡単に言うと、Shopify では、API を安全に利用するためにアプリケーションは認証が必要ですが、すべてのデータが認証を必要とするわけではなく、一部の情報は認証なしでアクセスできるようになっています。

認証の種類| Types of authentication

Shopify プラットフォームでは、アプリやサービスを認証するために複数の方法があります。開発を始める前に、これらの異なる認証方法の違いを理解することが重要です。

各認証方法は、アプリやサービスが Shopify のデータや機能にアクセスするための異なるプロトコルや手順を提供します。適切な認証方法を選択することで、アプリが安全に Shopify のリソースにアクセスし、ユーザーのデータを保護することができます。

簡単に言えば、Shopify でアプリやサービスを開発する際には、さまざまな認証オプションがあり、各オプションの違いを理解し選択することが開発の成功に重要です。

ShopifyAPI へのバックエンドリクエストの認証| Authenticating your backend requests to Shopify APIs

組み込みアプリでのマーチャントの認証| Authenticating merchants on embedded apps

Shopify のプラットフォームに接続する Web アプリケーションまたはサービスは、エンドユーザーにどのように公開されているかに関係なく、アプリと呼ばれます。さまざまな種類のアプリがさまざまな認証方法を使用します。

認証されていない API | Unauthenticated APIs

Shopify の Storefront API は認証されていません。つまり、ユーザーはユーザー名やパスワードなしで特定のデータにアクセスできます。 Storefront API は、このリスクに問題がない場合にのみ使用し、アクセスできるストアデータを制限する必要があります。データアクセスは、ストアフロントアクセストークンを作成するときに選択したアクセス許可によって制御されます。ストアフロントアクセストークンを作成した後、必要に応じてその API 権限を変更できます。

API アクセスモード| API access modes

トークンを作成するときは、2 つの異なるアクセスモードから選択できます。

トークンの適切なアクセスモードは、アプリのユースケースによって異なります。

Tip

必要に応じて異なるアクセストークンを使用することで、アプリが両方のアクセスモードを同時に使用することが可能です。

オンラインアクセス

Shopify のオンラインアクセスモードは、特定のユーザーの Web セッションにリンクされたアクセストークンを提供します。これは、ユーザーが Web を介してアプリを操作している場合や、アプリがユーザーの個々の権限レベルに基づいて機能する必要がある場合に使用されます。

オンラインアクセスモードの特徴は以下の通りです:

  • アクセストークンはユーザーの Web セッションの期間と同じです。セッションが終了すると、トークンも期限切れになります。
  • このアクセスモードは、認証プロセスの初期段階で明示的に要求される必要があります。
  • トークンを使った API リクエストは、そのユーザーに与えられた特定の権限に基づいて行われます。ユーザーがアクセス権を持っていない場合、Shopify はアクセスを拒否します。
  • アクセストークンは一時的で、有効期限が切れた場合、Shopify はアクセスを拒否します。
  • ユーザーは自分のアクセスをいつでも取り消すことができ、これにより他のユーザーのトークンには影響しません。
  • ユーザーが Shopify 管理者からログアウトすると、そのセッションで作成されたすべてのトークンは無効になります。
  • オンラインアクセストークンは、一時セッションストレージや Cookie を使用して管理され、API リクエスト時に適切に使用されます。
  • キャッシュを使用する場合、それはユーザーごとに異なる権限レベルを考慮して設計されるべきです。
  • アプリがストアにまだインストールされていない場合、オンラインアクセスモードが要求されると、インストールするユーザーは必要なすべてのアクセス権限を持っている必要があります。
    アプリがインストールされた後にこのモードをリクエストすると、利用可能なアクセススコープに基づいたトークンが提供されます。
  • 要するに、オンラインアクセスモードは、ユーザーのセッションと直接関連しており、個々のユーザーのアクセスレベルを尊重するために設計されています。

オフラインアクセス

オフラインアクセスモードのトークンは、ユーザーの直接的な操作なしに Shopify ストアへの長期間のアクセスを提供するために使用されます。このモードは、Webhook に対応するバックグラウンドタスクやバックグラウンドでのメンテナンス作業などに最適です。

オフラインアクセスモードの特徴は以下の通りです:

  • これはデフォルトのアクセスモードであり、特に指定されていない場合に適用されます。
  • 作成されたアクセストークンは永続的であり、アプリがストアからアンインストールされるまで有効です。
  • ユーザーの直接的な操作がない場合に適しているため、バックグラウンドプロセスに特に適しています。
  • オフラインアクセスでアプリを複数回承認すると、同じアクセストークンが毎回返されます。ストアへのアクセス権限を更新する必要がある場合や追加のアクセススコープが必要な場合にのみ、アプリを再承認する必要があります。
  • もしアプリがまだストアにインストールされていない場合、インストールを試みるユーザーは必要なすべてのアクセス権限を持っている必要があります。そうでなければ、インストールは失敗します。
  • アプリがストアにインストールされた後、アプリのスタッフの権限を持つすべてのユーザーは、その権限レベルに関わらず、- OAuth 認証プロセスを再度正常に完了することができます。
  • 要するに、オフラインアクセスモードは、ユーザーの積極的な介入なしにストアへの継続的なアクセスを可能にするためのものであり、特にバックグラウンドでの作業に適しています。

ツール| Tools

https://shopify.dev/apps/tools/cli

https://github.com/Shopify/shopify_app

https://www.npmjs.com/package/@shopify/koa-shopify-auth

GraphQL   AdminAPI を使用して一括操作を実行する

GraphQL Admin API を使用すると、一括操作を使用してデータを一括で非同期にフェッチできます。API は、大量のデータのページ付けを処理する際の複雑さを軽減するように設計されています。GraphQL AdminAPI スキーマで定義されている任意の接続フィールドを一括クエリできます。

結果を手動でページ付けしてクライアント側のスロットルを管理する代わりに、一括クエリ操作を実行できます。Shopify のインフラストラクチャは、クエリを実行するという大変な作業を行い、すべてのデータをダウンロードできる URL を提供します。

GraphQL Admin API は、単一の最上位フィールドのクエリを実行してから、返すフィールドを選択することをサポートしています。製品のバリエーションなど、接続をネストすることもできます。

アプリは、ショップごとに一度に 1 つの一括操作を実行するように制限されています。操作が完了すると、Shopify が URL で利用できるようにするJSONL file の形式で結果が配信されます。

一括操作は、GraphQL Admin APIを介してのみ利用できます。 REST AdminAPI または StorefrontAPI を使用して一括操作を実行することはできません。

一括クエリの導入

一括クエリを実行するための完全なフローについては後で説明しますが、以下は、すばやく開始するために使用できるいくつかの小さなコードスニペットです。

Step 1. クエリを送信する

bulkOperationRunQuery ミューテーションを実行し、Shopify に必要な情報を指定します。

次のミューテーションは、products の接続を照会し、各製品の ID とタイトルを返します。

POST /admin/api/2020-04/graphql.json

mutation {
  bulkOperationRunQuery(
    query: """
    {
      products {
        edges {
          node {
            id
            title
          }
        }
      }
    }
    """
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}

JSON response

{
  "data": {
    "bulkOperationRunQuery": {
      "bulkOperation": {
        "id": "gid:\/\/shopify\/BulkOperation\/720918",
        "status": "CREATED"
      },
      "userErrors": []
    }
  },
...
}

Step 2. オペレーションのステータスをポーリングする

操作の実行中に、currentBulkOperationフィールドを使用して進行状況を確認するためにポーリングする必要があります。objectCountフィールドは増分して操作の進行状況を示し、status フィールドは操作が完了したかどうかを返します。

POST /admin/api/2020-04/graphql.json

query {
  currentBulkOperation {
    id
    status
    errorCode
    createdAt
    completedAt
    objectCount
    fileSize
    url
    partialDataUrl
  }
}

JSON response

{
  "data": {
    "currentBulkOperation": {
      "id": "gid:\/\/shopify\/BulkOperation\/720918",
      "status": "COMPLETED",
      "errorCode": null,
      "createdAt": "2019-08-29T17:16:35Z",
      "completedAt": "2019-08-29T17:23:25Z",
      "objectCount": "57",
      "fileSize": "358",
      "url": "https:\/\/storage.googleapis.com\/shopify\/dyfkl3g72empyyoenvmtidlm9o4g?<params>",
      "partialDataUrl": null
    }
  },
  ...
}

Step 3. データを取得する

操作が完了すると、URLフィールドで指定された URL から JSONL 出力ファイルをダウンロードできます。クエリで結果が生成されなかった場合、urlフィールドはnullを返します。

返されるファイルの詳細については結果データのダウンロード を、解析方法については JSONL ファイル形式JSONL file format を参照してください。


一括クエリワークフロー

以下は、一括クエリを作成するための高レベルのワークフローです。

  1. 潜在的な一括操作を特定する.
    新規または既存のクエリを使用できますが、大量のデータが返される可能性があります。接続ベースのクエリが最適です。

  2. Shopify GraphiQL アプリ.を使用してクエリをテストします。

  3. bulkOperationRunQueryのための新しいミューテーションドキュメントを作成します

  4. ミューテーションのqueryの値としてクエリを含めます。

  5. ミューテーションを実行します。

  6. statusフィールドに操作が実行されなくなったことが示されるまで、一括操作をポーリングしますobjectCountフィールドを使用して、操作の進行状況を確認できます 。

  7. URLフィールドに指定された URL で JSONL ファイルをダウンロードします

潜在的な一括クエリを特定する

大量のデータを返す可能性があり、一括操作のメリットを享受できる新規または既存のクエリを特定します。
結果のすべてのページを取得するためにページ付けを使用するクエリは、最も一般的な候補です。

以下のクエリ例は、2019 年 1 月 1 日以降に作成されたストアの最初の 50 個の商品からいくつかの基本情報を取得します。

{
  products(query: "created_at:>=2020-01-01 AND created_at:<2020-05-01", first: 50) {
    edges {
      cursor
      node {
        id
        createdAt
        updatedAt
        title
        handle
        descriptionHtml
        productType
        options {
          name
          position
          values
        }
        priceRange {
          minVariantPrice {
            amount
            currencyCode
          }
          maxVariantPrice {
            amount
            currencyCode
          }
        }
      }
    }
    pageInfo {
      hasNextPage
    }
  }
}

Shopify GraphiQL appを使用して、開発ストアに対してこのクエリを実行します。一括操作で使用されるクエリには、通常のクエリとして実行する場合と同じ権限が必要です。したがって、最初にクエリを実行し、アクセス拒否エラーなしで成功することを確認することが重要です。

一括操作を書く

上記のクエリを一括クエリに変換するには、bulkOperationRunQueryミューテーションを使用します。queryのバリューなしでスケルトンミューテーションから始めるのが最も簡単です。

mutation {
  bulkOperationRunQuery(
    query: """

    """
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}
  • 三重引用符( "" ")は、GraphQL で複数行の文字列を定義します。
  • 一括操作の ID が返されるため、操作をポーリングできます。
  • エラーメッセージを取得するために、userErrorsフィールドが返されます。

元のサンプルクエリをミューテーションに貼り付けてから、オプションでいくつかの小さな変更を加えます。

  • firstの引数はオプションであり、存在する場合は無視されるため、削除できます。
  • cursorフィールドとpageInfoフィールドもオプションであり、存在する場合は無視されるため、削除できます。
mutation {
  bulkOperationRunQuery(
    query: """
    {
      products(query: "created_at:>=2020-01-01 AND created_at:<2020-05-01") {
        edges {
          node {
            id
            createdAt
            updatedAt
            title
            handle
            descriptionHtml
            productType
            options {
              name
              position
              values
            }
            priceRange {
              minVariantPrice {
                amount
                currencyCode
              }
              maxVariantPrice {
                amount
                currencyCode
              }
            }
          }
        }
      }
    }
    """
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}

ミューテーションが成功した場合、応答は次の例のようになります。

{
  "data": {
    "bulkOperationRunQuery": {
      "bulkOperation": {
        "id": "gid:\/\/shopify\/BulkOperation\/1",
        "status": "CREATED"
      },
      "userErrors": []
    }
  },
  ...
}

実行中の一括操作をポーリングする

一括操作は非同期で長時間実行されるため、いつ完了するかを調べるためにポーリングする必要があります。これを行う最も簡単な方法は、currentBulkOperationフィールドを照会することです。

{
  currentBulkOperation {
    id
    status
    errorCode
    createdAt
    completedAt
    objectCount
    fileSize
    url
    partialDataUrl
  }
}

このフィールドは、認証されたアプリとショップに対して(ステータスに関係なく)作成された最新の一括操作を返します。 ID で特定の操作を検索する場合は、nodeフィールドを使用できます。

{
  node(id: "gid://shopify/BulkOperation/1") {
    ... on BulkOperation {
      id
      status
      errorCode
      createdAt
      completedAt
      objectCount
      fileSize
      url
      partialDataUrl
    }
  }
}

予想されるデータ量に基づいて、ポーリング間隔を調整できます。たとえば、現在手動 ​​ でページ付けクエリを実行していて、すべての商品データを取得するのに 1 時間かかる場合、それは一括操作時間の概算として役立ちます。この状況では、1 分のポーリング間隔が 10 秒ごとよりもおそらく良いでしょう。

その他の可能な操作ステータスについては、BulkOperationStatus リファレンスを参照してください。

操作の進行状況を確認する

ポーリングは、操作が完了したかどうかを確認するのに役立ちますが、objectCountフィールドを使用して操作の進行状況を確認するためにも使用できます。

{
  currentBulkOperation {
    status
    objectCount
    url
  }
}

たとえば、1 か月で作成されたすべての商品をクエリしようとしていて、オブジェクト数が予想数を超えている場合は、クエリ条件が間違っていることを示している可能性があります。その場合、現在の操作をキャンセルして、別のクエリで新しい操作を実行することをお勧めします。


結果データをダウンロードする

操作の実行が終了すると、結果データが利用可能になります。

操作が正常に完了すると、urlフィールドにデータをダウンロードできる URL が含まれます。操作が失敗したが、失敗が発生する前に一部のデータが取得された場合、partialDataUrlフィールドで指定された URL で部分的に完全な出力ファイルを使用できます。いずれの場合も、返される URL は署名(認証)され、1 週間後に期限切れになります。

データをダウンロードしたので、JSONL 形式に従ってデータを解析します。


JSONL データ形式

通常の(バルクではない)GraphQL 応答は JSON です。応答構造はクエリ構造を反映しているため、ネストされたオブジェクトが多数含まれる単一の JSON オブジェクトになります。ほとんどの標準的な JSON パーサーでは、文字列またはファイル全体をメモリに読み込む必要があります。これにより、応答が大きい場合に問題が発生する可能性があります。

一括操作は大規模なデータセットをフェッチするように特別に設計されているため、クライアントがデータを消費する方法に柔軟性を持たせるために、応答データに JSON Lines (JSONL)形式を選択しました。JSONL は JSON に似ていますが、各行は独自の有効な JSON オブジェクトです。メモリ消費の問題を回避するために、ほとんどの言語にあるファイルストリーミング機能を使用して、ファイルを一度に 1 行ずつ解析できます。

ファイルの各行は、接続で返されるノードオブジェクトです。ノードにネストされた接続がある場合、各子ノードは次の行の独自のオブジェクトに抽出されます。たとえば、一括操作では、次のクエリを使用して、製品とそのネストされた variants 型のリストを取得できます。

{
  products {
    edges {
      node {
        id
        variants {
          edges {
            node {
              id
              title
            }
          }
        }
      }
    }
  }
}

JSONL の結果では、各製品オブジェクトの後に、新しい行にその variants 型オブジェクトが続きます。各接続タイプの順序は保持され、ネストされたすべての接続はファイル内の親の後に表示されます。ただし、子ノードは親の直後に表示されない場合があります。たとえば、次の結果では、タイトル52の製品 variants は、ファイルの最初の製品の子です。

{"id":"gid://shopify/Product/1921569226808"}
{"id":"gid://shopify/ProductVariant/19435458986040","title":"70","__parentId":"gid://shopify/Product/1921569226808"}
{"id":"gid://shopify/Product/1921569259576"}
{"id":"gid://shopify/ProductVariant/19435459018808","title":"34","__parentId":"gid://shopify/Product/1921569259576"}
{"id":"gid://shopify/Product/1921569292344"}
{"id":"gid://shopify/ProductVariant/19435459051576","title":"Default Title","__parentId":"gid://shopify/Product/1921569292344"}
{"id":"gid://shopify/Product/1921569325112"}
{"id":"gid://shopify/ProductVariant/19435459084344","title":"36","__parentId":"gid://shopify/Product/1921569325112"}
{"id":"gid://shopify/Product/1921569357880"}
{"id":"gid://shopify/ProductVariant/19435459117112","title":"47","__parentId":"gid://shopify/Product/1921569357880"}
{"id":"gid://shopify/ProductVariant/19435458986123","title":"52","__parentId":"gid://shopify/Product/1921569226808"}

ネストされた接続は応答データ構造にネストされなくなったため、結果にはオブジェクトの親への参照である__parentIdフィールドが含まれます。このフィールドは API スキーマに存在しないため、明示的にクエリすることはできません。一括操作結果に自動的に含まれます。

GraphQL Admin API は、JSONL ファイルの内容をシリアルに処理しません。目的の結果を達成するために、特定の行のシーケンスとオブジェクトの順序に依存することは避けてください。

JSONL ファイルを逆に読む

JSONL ファイルを逆に読み取ると、子ノードのグループ化が容易になり、親ノードの後に ​​ 表示されるノードが失われる。たとえば、バリアントを収集している間、variants が属する製品に到達したときに、ファイルのさらに上にバリアントが存在することはありません。JSONL ファイルをダウンロードした後、それを逆に読み取り、それを解析して、親ノードが検出される前に子ノードが追跡されるようにします。

ほとんどのプログラミング言語には、ファイル全体がメモリに読み込まれないように、一度に 1 行ずつファイルを読み取る機能があります。この機能は、JSONL データファイルを処理するときに利用する必要があります。

これは、JSONL ファイルをロードして解析する適切な方法を示す Ruby の簡単な例です。

# Efficient: reads the file a single line at a time
File.open(file) do |f|
  f.each do |line|
    JSON.parse(line)
  end
end

# Inefficient: reads the entire file into memory
jsonl = File.read(file)

jsonl.each_line do |line|
  JSON.parse(line)
end

100MB の JSONL ファイルを使用した場合の違いを示すために、「良い」バージョンは 2.5MB のメモリしか消費しませんが、「悪い」バージョンは 100MB(ファイルサイズに等しい)を消費します。

他の言語:


実行の失敗

フィールドをクエリする権限がないなど、通常の GraphQL クエリが失敗する理由のいずれかにより、一括操作が失敗する可能性があります。このため、最初にクエリを通常どおり実行して、クエリが機能することを確認することをお勧めします。一括操作でクエリが失敗した場合よりも、はるかに優れたエラーフィードバックが得られます。

一括操作が失敗した場合、そのstatusフィールドはFAILEDを返し、errorCodeフィールドには次のコードが含まれます。

  • ACCESS_DENIED:アクセススコープがありません。クエリを通常どおり(一括操作以外で)実行して、問題の原因となっているフィールドの詳細を取得します。
  • INTERNAL_SERVER_ERROR:サーバーで問題が発生し、エラーが通知されました。これらのエラーは断続的に発生する可能性があるため、クエリの送信を再試行できます
  • TIMEOUT:実行中に 1 つ以上のクエリタイムアウトが発生しました。クエリを正常に実行できるように、クエリからいくつかのフィールドを削除してみてください。これらのタイムアウトは断続的に発生する可能性があるため、 クエリの送信を再試行できます

その他の考えられる操作エラーコードについては、BulkOperationErrorCode リファレンスを参照してください。

キャンセルされた操作

一括操作が停止した場合、Shopify によってキャンセルされる可能性があります。一括操作がキャンセルされた後、CANCELEDstatusが返されます。クエリを再送信することで、キャンセルされた一括操作を再試行できます。


操作のキャンセル

進行中の一括操作をキャンセルするには、操作 ID でbulkOperationCancelミューテーションを使用します。

mutation {
  bulkOperationCancel(id: "gid://shopify/BulkOperation/1") {
    bulkOperation {
      status
    }
    userErrors {
      field
      message
    }
  }
}

レート制限

現在、ショップごとに(アプリごとに)アクティブな(実行中の)一括操作は常に1 つだけです。この制限は、操作が非同期で長時間実行されるために適用されます。

一括操作が AdminAPI のレート制限内にどのように収まるか

バルク操作は、bulkOperationRunQueryミューテーション内にクエリ文字列を指定することにより、API コンシューマーであるユーザーによって開始されます。次に、Shopify はそのquery文字列を一括操作として非同期に実行します。 BulkOperationRunQueryミューテーションとバルクquery文字列自体のこの違いにより、レート制限の適用方法も決まります。ユーザーが行った GraphQL リクエストは、通常の API リクエストとしてカウントされ、レート制限の対象となりますが、一括操作クエリの実行は対象外です。

次の例では、(他のミューテーションと同様に)ミューテーションリクエストのコストが請求されますが、Shopify で一括操作として実行する製品タイトルのqueryについては請求されません。

mutation {
  bulkOperationRunQuery(
    query: """
    {
      products {
        edges {
          node {
            title
          }
        }
      }
    }
    """
  ) {
    bulkOperation {
      id
    }
  }
}

操作の作成、ステータスのポーリング、またはキャンセルのために低コストのリクエストを行うだけなので、一括操作は、標準のページ付けクエリと比較して、データをクエリするための非常に効率的な方法です。


動作制限

一括操作クエリには接続を含める必要があります。クエリが接続を使用しない場合は、通常の同期 GraphQL クエリとして実行する必要があります。

一括操作には、いくつかの追加の制限があります。

  • クエリ内の合計接続数は最大 5 つです。
  • 最上位のnodeおよび``nodes`フィールドは使用できません。
  • ネストされた接続の場合、最大 2 レベルの深さ。たとえば、ネストされた接続には 3 つのレベルがあるため、以下は無効です。
{
  products {
    edges {
      node {
        id
        variants {
          # nested level 1
          edges {
            node {
              id
              images {
                # nested level 2
                edges {
                  node {
                    id
                    metafields {
                      # nested level 3 (invalid)
                      edges {
                        node {
                          value
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

BulkOperationRunQueryミューテーションは、提供されたクエリを検証し、userErrorsフィールドを使用してエラーを提供します。
GraphQL クエリの柔軟性が許可されているものと提供されていないものの完全な例を提供するのは難しいので、いくつか試してみて、何が機能し、何が機能しないかを確認してください。まだサポートされていない有用なクエリを見つけた場合は、forumsでお知らせください。一般的な使用例を収集できます。


次のステップ

GraphQL AdminAPI を使用したデータの一括インポート

従来の同期 API を使用して大量のデータをインポートすると、処理が遅く、実行が複雑になり、管理が困難になります。GraphQL ミューテーションを手動で複数回実行し、クライアント側のスロットルを管理する代わりに、バルクミューテーション操作を実行できます。

GraphQL Admin API を使用すると、大量のデータを非同期で一括インポートできます。操作が完了すると、Shopify が URL で利用できるようにするJSON Lines (JSONL)ファイルで結果が配信されます。

このガイドでは、bulkOperationRunMutationを紹介し、それを使用してデータを Shopify に一括インポートする方法を示します。


要件


制限事項

この制限は、操作が非同期で長時間実行されるために適用されます。ショップに対して後続のバルクミューテーション操作を実行するには、実行中の操作をキャンセルするか、実行が終了するのを待つ必要があります。


データの一括インポートの仕組み

バルク操作を開始するには、bulkOperationRunMutationにミューテーション文字列を指定します。次に、Shopify は、そのミューテーション文字列を一括操作として非同期に実行します。

作成するほとんどの GraphQLAdmin API リクエストにはレート制限が適用されますが、bulkOperationRunMutationリクエストには適用されません。操作の作成、ステータスのポーリング、またはキャンセルのために低コストのリクエストを行うだけなので、バルクミューテーション操作は、標準の GraphQLAPI リクエストと比較してデータを作成するための効率的な方法です。

次の図は、Shopify へのデータの一括インポートに関連する手順を示しています。

Workflow for bulk importing data

  1. JSONL ファイルを作成し、GraphQL 変数を含めます :ミューテーションの変数を JSONL ファイル形式で含めます。 JSONL ファイルの各行は、1 つの入力ユニットを表します。ミューテーションは、入力ファイルの各行で 1 回実行されます。
  2. ファイルを Shopify にアップロードする:ファイルをアップロードする前に、stagedUploadsCreateミューテーションを実行してリンクを予約する必要があります。スペースが予約された後、stagedUploadsCreate応答から返された情報を使用して要求を行うことにより、ファイルをアップロードできます。
  3. 一括変更操作の作成:ファイルがアップロードされたら、bulkOperationRunMutationを実行して一括変更操作を作成できます。 bulkOperationRunMutationは、最後のステップでアップロードされた変数のファイルを使用して、提供された GraphQL API ミューテーションを実行することにより、データを一括でインポートします。
  4. 操作のステータスをポーリングする:操作の実行中に、currentBulkOperationフィールドを使用して進行状況を確認するためにポーリングする必要があります。bulkOperationオブジェクトのobjectCountフィールドは、操作の進行状況を示すために増分し、statusフィールドは、操作が完了したかどうかを示すブール値を返します。
  5. 結果の取得:一括変更操作が完了すると、URLフィールドで指定された URL から JSONL 出力ファイルをダウンロードできます。

JSONL ファイルを作成し、GraphQL 変数を含めます

GraphQL 変数を新しい JSONL ファイルに追加するときは、対応する一括操作 GraphQLAPI によって受け入れられるように変数をフォーマットする必要があります。入力変数の形式は、GraphQL AdminAPI スキーマと一致する必要があります。

たとえば、大量の製品をインポートしたい場合があります。製品の各属性は、GraphQL 入力オブジェクト ProductInputで定義された既存のフィールドにマップする必要があります。JSONL ファイルでは、各行は 1 つの製品入力を表します。 GraphQL Admin API は、入力ファイルの各行で 1 回実行されます。入力オブジェクトの構造がどれほど複雑であっても、1 つの入力は 1 行だけを占める必要があります。

次の例は、10 個の製品をまとめて作成するために使用されるサンプル JSONL ファイルを示しています。

{ "input": { "title": "Sweet new snowboard 1", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 2", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 3", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 4", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 5", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 6", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 7", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 8", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 9", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 10", "productType": "Snowboard", "vendor": "JadedPixel" } }

GraphQL Admin API は、JSONL ファイルの内容をシリアルに処理しません。目的の結果を達成するために、特定の行のシーケンスとオブジェクトの順序に依存することは避けてください。


ファイルを Shopify にアップロードします

JSONL ファイルを作成し、GraphQL 変数を含めたら、ファイルを Shopify にアップロードできます。ファイルをアップロードする前に、まずアップロード URL とパラメーターを生成する必要があります。

アップロードされた URL とパラメータを生成します

stagedUploadsCreateミューテーションを使用して、アップロードの認証に必要な値を生成できます。ミューテーションは、stagedMediaUploadTargetインスタンスの配列を返します。

stagedMediaUploadTargetのインスタンスには、次の主要なプロパティがあります。

  • parameters:アップロードリクエストの認証に使用するパラメータ。
  • url:GraphQL 変数を含む JSONL ファイルをアップロードできる署名付き URL。

ミューテーションは、次のフィールドを持つタイプstagedUploadInputの入力を受け入れます。

フィールド説明
resourceenumアップロードするリソースタイプを指定します。 BulkOperationRunMutationを使用するには、リソースタイプがBULK_MUTATION_VARIABLESである必要があります。
filenamestringアップロードするファイルの名前。
mimeTypestringアップロードするファイルのmedia typeBulkOperationRunMutationを使用するには、mimeType「text / jsonl」である必要があります。
httpMethodenum段階的アップロードで使用される HTTP メソッド。 BulkOperationRunMutationを使用するには、httpMethodPOSTである必要があります。

次の例では、stagedUploadsCreateミューテーションを使用して、JSONL ファイルをアップロードし、bulkOperationRunMutationによって消費されるために必要な値を生成します。最初に変数なしでstagedUploadsCreateミューテーションを実行してから、JSONL データを使用して段階的なアップロード URL に POST リクエストを個別に送信する必要があります。

リクエスト
POST /admin/api/2021-07/graphql.json

mutation {
  stagedUploadsCreate(
    input: {
      resource: BULK_MUTATION_VARIABLES
      filename: "bulk_op_vars"
      mimeType: "text/jsonl"
      httpMethod: POST
    }
  ) {
    userErrors {
      field
      message
    }
    stagedTargets {
      url
      resourceUrl
      parameters {
        name
        value
      }
    }
  }
}

JSON response:

{
  "data": {
    "stagedUploadsCreate": {
      "userErrors": [],
      "stagedTargets": [
        {
          "url": "https://shopify.s3.amazonaws.com",
          "resourceUrl": null,
          "parameters": [
            {
              "name": "key",
              "value": "tmp/21759409/bulk/89e620e1-0252-43b0-8f3b-3b7075ba4a23/bulk_op_vars"
            },
            {
              "name": "Content-Type",
              "value": "text/jsonl"
            },
            {
              "name": "success_action_status",
              "value": "201"
            },
            {
              "name": "acl",
              "value": "private"
            },
            {
              "name": "policy",
              "value": "eyJleHBpcmF0aW9uIjoiMjAyMS0wMS0yOFQyMDowNTo0NloiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJzaG9waWZ5In0sWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMSwyMDk3MTUyMF0seyJrZXkiOiJ0bXAvMjE3NTk0MDkvYnVsay84OWU2MjBlMS0wMjUyLTQzYjAtOGYzYi0zYjcwNzViYTRhMjMvYnVsa19vcF92YXJzIn0seyJDb250ZW50LVR5cGUiOiJ0ZXh0L2pzb25sIn0seyJzdWNjZXNzX2FjdGlvbl9zdGF0dXMiOiIyMDEifSx7ImFjbCI6InByaXZhdGUifSx7IngtYW16LWNyZWRlbnRpYWwiOiJBS0lBSllNNTU1S1ZZRVdHSkRLUS8yMDIxMDEyOC91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1kYXRlIjoiMjAyMTAxMjhUMTkwNTQ2WiJ9XX0="
            },
            {
              "name": "x-amz-credential",
              "value": "AKIAJYM555KVYEWGJDKQ/20210128/us-east-1/s3/aws4_request"
            },
            {
              "name": "x-amz-algorithm",
              "value": "AWS4-HMAC-SHA256"
            },
            {
              "name": "x-amz-date",
              "value": "20210128T190546Z"
            },
            {
              "name": "x-amz-signature",
              "value": "5d063aac44a108f2e38b8294ca0e82858e6f44baf835eb81c17d37b9338b5153"
            }
          ]
        }
      ]
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 11,
      "actualQueryCost": 11
    }
  }
}

JSON ファイルをアップロードする

アップロード用のパラメーターと URL を生成した後、POST リクエストを使用して JSONL ファイルをアップロードできます。マルチパートフォームを使用し、すべてのパラメーターをフォーム入力としてリクエスト本文に含める必要があります。

マルチパートフォームのパラメーターを生成するには、stagedUploadsCreateミューテーションから返されたパラメーターから始めます。次に、添付ファイルを追加します。

fileパラメータは、リストの最後のパラメータである必要があります。fileパラメータを別の場所に追加すると、エラーが発生します。

POST request

curl --location --request POST 'https://shopify.s3.amazonaws.com' \
--form 'key="tmp/21759409/bulk/89e620e1-0252-43b0-8f3b-3b7075ba4a23/bulk_op_vars"' \
--form 'x-amz-credential="AKIAJYM555KVYEWGJDKQ/20210128/us-east-1/s3/aws4_request"' \
--form 'x-amz-algorithm="AWS4-HMAC-SHA256"' \
--form 'x-amz-date="20210128T190546Z"' \
--form 'x-amz-signature="5d063aac44a108f2e38b8294ca0e82858e6f44baf835eb81c17d37b9338b5153"' \
--form 'policy="eyJleHBpcmF0aW9uIjoiMjAyMS0wMS0yOFQyMDowNTo0NloiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJzaG9waWZ5In0sWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMSwyMDk3MTUyMF0seyJrZXkiOiJ0bXAvMjE3NTk0MDkvYnVsay84OWU2MjBlMS0wMjUyLTQzYjAtOGYzYi0zYjcwNzViYTRhMjMvYnVsa19vcF92YXJzIn0seyJDb250ZW50LVR5cGUiOiJ0ZXh0L2pzb25sIn0seyJzdWNjZXNzX2FjdGlvbl9zdGF0dXMiOiIyMDEifSx7ImFjbCI6InByaXZhdGUifSx7IngtYW16LWNyZWRlbnRpYWwiOiJBS0lBSllNNTU1S1ZZRVdHSkRLUS8yMDIxMDEyOC91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1kYXRlIjoiMjAyMTAxMjhUMTkwNTQ2WiJ9XX0="' \
--form 'acl="private"' \
--form 'Content-Type="text/jsonl"' \
--form 'success_action_status="201"' \
--form 'file=@"/Users/username/Documents/bulk_mutation_tests/products_long.jsonl"'

GraphQL variables in JSONL file

{ "input": { "title": "Sweet new snowboard 1", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 2", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 3", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 4", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 5", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 6", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 7", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 8", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 9", "productType": "Snowboard", "vendor": "JadedPixel" } }
{ "input": { "title": "Sweet new snowboard 10", "productType": "Snowboard", "vendor": "JadedPixel" } }

バルクミューテーション操作を作成する

ファイルをアップロードした後、bulkOperationRunMutationを実行して、データを一括でインポートできます。対応するミューテーションと前の手順で取得した URL を指定する必要があります。

bulkOperationRunMutationミューテーションは、次の引数を取ります。

フィールド説明
mutationstring一括で実行する GraphQLAPI ミューテーションを指定します。有効な値:productCreatecollectionCreateproductUpdateproductUpdateMediaproductVariantUpdate
stagedUploadPathstringstagedUploadsCreateによって使用される JSONL 形式の入力ファイルへのパス

次の例では、次のproductCreateミューテーションを一括で実行します。

mutation call($input: ProductInput!) {
  productCreate(input: $input) {
    product {
      id
      title
      variants(first: 10) {
        edges {
          node {
            id
            title
            inventoryQuantity
          }
        }
      }
    }
    userErrors {
      message
      field
    }
  }
}

productCreateミューテーションを一括で実行するには、ミューテーションを文字列としてbulkOperationRunMutationに渡します。

Request
POST /admin/api/2021-07/graphql.json

mutation {
  bulkOperationRunMutation(
    mutation: "mutation call($input: ProductInput!) { productCreate(input: $input) { product {id title variants(first: 10) {edges {node {id title inventoryQuantity }}}} userErrors { message field } } }"
    stagedUploadPath: "tmp/21759409/bulk/89e620e1-0252-43b0-8f3b-3b7075ba4a23/bulk_op_vars"
  ) {
    bulkOperation {
      id
      url
      status
    }
    userErrors {
      message
      field
    }
  }
}

JSON response:

{
  "data": {
    "bulkOperationRunMutation": {
      "bulkOperation": {
        "id": "gid://shopify/BulkOperation/206005076024",
        "url": null,
        "status": "CREATED"
      },
      "userErrors": []
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 10,
      "actualQueryCost": 10
    }
  }
}

操作のステータスをポーリングします

一括操作は非同期であり、大きな入力ファイルの場合は長時間実行される可能性があるため、ポーリングを実行して、いつ完了したかを確認する必要があります。ポーリングする最も簡単な方法は、currentBulkOperationフィールドを照会することです。

インポートするデータの量に基づいて、ポーリング間隔を調整できます。その他の考えられる操作ステータスについては、BulkOperationStatusリファレンスドキュメントを参照してください。

操作のステータスをポーリングするには、次のリクエスト例を使用します。

Request
POST /admin/api/2021-07/graphql.json

query {
  currentBulkOperation(type: MUTATION) {
    id
    status
    errorCode
    createdAt
    completedAt
    objectCount
    fileSize
    url
    partialDataUrl
  }
}

JSONresponse

{
  "data": {
    "currentBulkOperation": {
      "id": "gid://shopify/BulkOperation/206005076024",
      "status": "COMPLETED",
      "errorCode": null,
      "createdAt": "2021-01-28T19:10:59Z",
      "completedAt": "2021-01-28T19:11:09Z",
      "objectCount": "16",
      "fileSize": "6155",
      "url": "https://storage.googleapis.com/shopify-tiers-assets-prod-us-east1/iqtpj52yuoa7prkbpzp9gwn27kw3?GoogleAccessId=assets-us-prod%40shopify-tiers.iam.gserviceaccount.com&Expires=1612465869&Signature=KOhlcYhLve3NLr6rfVbAeY02crFAM3rMrDNfTSlgT%2FScI%2B8o%2B%2FdO99F3UseC837uWA6FzfrNhxdRNqhBN%2F8ekBTW7IyPRD6ho5phfE8MTaev4ltQrJygJTDbjXfX5KLJOuY8siH%2FDrc4gctZsMsNaf2%2FYp%2FaDzBzjfxJge8i8he69t0uZ39FBXrMxCeMVd6lU8%2FbgMuO80rTHjgI%2BlC8g2%2FWiHyq5rSTDLIxxGWRCddMfPcaivdWVdMubMa0wOt9W9R2mfjuTAgUBexUkJwhvrkdof%2Bg00gU1g4dIBWlUSO5D9tdrv9bmIy7FceopNufrpwnD1NXU8Narsx2yEQ6aA%3D%3D&response-content-disposition=attachment%3B+filename%3D%22bulk-206005076024.jsonl%22%3B+filename%2A%3DUTF-8%27%27bulk-206005076024.jsonl&response-content-type=application%2Fjsonl",
      "partialDataUrl": null
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 1,
      "actualQueryCost": 1
    }
  }
}

結果を取得する

バルクミューテーション操作が終了したら、結果データファイルをダウンロードできます。

操作が正常に完了すると、urlフィールドにはデータファイルをダウンロードできる URL が含まれます。操作が失敗したが、失敗が発生する前に一部のデータが取得された場合、partialDataUrlフィールドで指定された URL で部分的に完全なデータファイルを利用できます。

いずれの場合も、返された URL は認証され、1 週間後に期限切れになります。

データをダウンロードしたら、JSONL 形式に従って解析できます。入力ファイルと応答ファイルの両方が JSONL にあるため、最終的なアセットファイルの各行は、入力ファイルの対応する行でミューテーションを実行したときの応答を表します。

操作の成功

次の例は、正常に作成された製品の応答を示しています。

{
  "data": {
    "productCreate": {
      "product": {
        "id": "gid://shopify/Product/5602345320504",
        "title": "Monday morning snowboard 1",
        "variants": {
          "edges": [
            {
              "node": {
                "id": "gid://shopify/ProductVariant/35645836853304",
                "title": "First",
                "inventoryQuantity": 0
              }
            },
            {
              "node": {
                "id": "gid://shopify/ProductVariant/35645836886072",
                "title": "Second",
                "inventoryQuantity": 0
              }
            }
          ]
        }
      },
      "userErrors": []
    }
  },
  "__lineNumber": 0
}

操作の失敗

特定の API にアクセスする権限がないなど、通常の GraphQL API ミューテーションが失敗する理由のいずれかにより、一括操作が失敗する可能性があります。このため、最良のアプローチは、最初に単一の GraphQL ミューテーションを実行して、バルク操作の一部としてミューテーションを実行する前に、それが機能することを確認することです。

一括操作が失敗した場合、そのstatusフィールドはFAILEDを返し、errorCodeフィールドは次のいずれかのコードを返します。

  • ACCESS_DENIED:アクセススコープがありません。ミューテーションを通常どおり(一括操作の外で)実行して、問題の原因となっているフィールドの詳細を取得します。
  • INTERNSL_SERVER_ERROR:Shopify のサーバーで問題が発生し、エラーが通知されました。これらのエラーは断続的に発生する可能性があるため、もう一度リクエストしてみてください。
  • TIMEOUT:実行中に 1 つ以上のミューテーションタイムアウトが発生しました。クエリを正常に実行できるように、クエリからいくつかのフィールドを削除してみてください。これらのタイムアウトは断続的に発生する可能性があるため、クエリの送信を再試行できます。

その他の考えられる操作エラーコードについては、BulkOperationErrorCodeリファレンスドキュメントを参照してください。

検証エラー

入力の形式が正しいが、1 つ以上の値が製品作成サービスの検証に失敗した場合、応答は次のようになります。

{"data"=>{"productCreate"=>{"userErrors"=>[{"message"=>"Some error message", "field"=>["some field"]}]}}}

認識できないフィールドエラー

入力に認識できないフィールドがある場合、応答は次のようになります。

{"errors"=>[{"message"=>"Variable input of type ProductInput! was provided invalid value for myfavoriteaddress (Field is not defined on ProductInput)", "locations"=>[{"line"=>1, "column"=>13}], "extensions"=>{"value"=>{"myfavoriteaddress"=>"test1"}, "problems"=>[{"path"=>["myfavoriteaddress"], "explanation"=>"Field is not defined on ProductInput"}]}}]}

このチェックは、入力を、mutation 引数の一部として指定されているproductInputオブジェクトと比較することによって実行されます。


操作をキャンセルする

進行中のバルク操作をキャンセルするには、 bulkOperationCancelミューテーションを実行し、操作 ID を入力変数として指定します。
Request
POST /admin/api/2021-07/graphql.json

mutation {
  bulkOperationCancel(id: "gid://shopify/BulkOperation/1") {
    bulkOperation {
      status
    }
    userErrors {
      field
      message
    }
  }
}

次のステップ

idempotent リクエスト

Shopify API は idempotency をサポートしています。これにより、接続の問題で失敗したかもしれない API リクエストを、重複や競合を引き起こすことなく安全に再試行することができます。

idempotency キー

idempotency key (idempotencyKey) または unique token (unique_token) は、あなたのアプリによって生成されたユニークな文字列識別子です。Shopify はこの識別子を使用して、同じリクエストの再試行を認識します。

idempotent リクエストの仕組み

API リクエストが転送中に中断された場合、レスポンスを受け取れない可能性があります。リクエストに idempotency key を含めることで、同じパラメータを持つリクエストが何度再試行されても、一度だけ実行されます。

例えば、Shopify で支払いを処理するために REST Admin API を使用しているとします。ネットワーク接続エラーのためにレスポンスを受信できなかった場合、同じunique_tokenを使ってリクエストを再試行することで、1 つの支払いだけが処理されることが保証されます。

POST /admin/checkouts/#{token}/payments.json HTTP/1.1
Host: shop-name.myshopify.com
Content-Type: application/json
X-Shopify-Access-Token: #{shopify_access_token}

{
  "payment": {
    "request_details": {
      "ip_address": "123.1.1.1",
      "accept_language": "en-US,en;q=0.8,fr;q=0.6",
      "user_agent": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/54.0.2840.98 Safari\/537.36"
    },
    "amount": "1675.99",
    "session_id": #{id},
    "unique_token": "client-side-idempotency-key"
  }
}

idempotency key には、任意の一意の識別子を使用できますが、衝突を避けるために、ランダムに生成された universally unique identifier(UUID)を使用することをお勧めします。

idempotency キーを受け付けるリソース

クレジットカードの支払いを処理する POST リクエスト、サブスクリプションのための請求書を作成するリクエスト、または収益の詳細を取得するリクエストは、idempotency キーを受け入れます。GET および DELETE リクエストは、定義上、idempotency であり、リクエストの一部として idempotency キーを送信する必要はありません。

idempotency key(GraphQL)やユニークトークン(REST)を受け付けるリソースの例としては、以下のものがあります。

GraphQL Admin API

GraphQL Storefront API

REST Admin API

Shopify APIs について

Shopify は、開発者がプラットフォームに組み込まれた機能を拡張できるよう一連の API を提供しています。これらの API により、パートナーは販売者データの読み書き、他のシステムやプラットフォームとの相互運用、Shopify への新機能の追加を行うことができます。


Shopify の API を使用するための要件


スコープとパーミッション

  • 一部の API 機能はプレミアムプランの販売者にのみ提供されます。
  • 作成するアプリの種類によっては、販売者がアプリをインストールする際に特定のパーミッションやアクセススコープを要求する必要があります。
  • いくつかの API では、Shopify にアクセスを要求し承認されてからコールを開始する必要があります。

利用可能な API

Admin API

Admin API は、販売者のストア、商品、注文などのデータを読み書きするために使用します。Admin API を使用して、Shopify admin (販売者が使用するストア管理インターフェイス) に機能を追加するアプリケーションを構築することができます。Admin API は、GraphQL (推奨) または REST を使用してアクセスできます。

Admin API の詳細はこちら

Storefront API

Storefront API は、オンラインストアや Shopify POS のような Shopify に組み込まれた販売ルートを超えて、Web、モバイル、ゲーム環境に Shopify の購買体験を拡張するために使用されます。開発者は顧客や商品のデータを扱うことができ、カスタムストアフロントを作成することができます。このアプローチをヘッドレスコマースと呼ぶこともあります。

Storefront API は、GraphQLを使ってアクセスできます。Storefront API にアクセスするには、未認証のアクセススコープを持つ Storefront アクセストークンが必要です。

Storefront API の詳細はこちら

Partner API

Partner API は、パートナーダッシュボードに表示されるデータにプログラムでアクセスするために使用されます。このアクセスにより、パートナーはフロントオフィスとバックオフィスのオペレーションを自動化することで、ビジネスを効果的に拡大することができ、Shopify 販売者への価値提供に時間を割くことができます。

Partner API はGraphQLを使ってアクセスできます。

Partner API の詳細はこちら

Liquid

Liquid テンプレート言語Shopify のテーマを作成するために使用されます。Liquid はオープンソースの言語で、静的な HTML と動的な Liquid タグを組み合わせるために、他の何千ものプロジェクトで使用されています。Liquid は Ruby の構文をベースにしています。

オープンソース版の Liquid で利用できる標準的なテンプレート機能に加えて、Shopify ストアはショップデータの API として機能する Liquid オブジェクトの追加セットにアクセスできます。Shopify Liquid では、商品コレクション、割引コード、配送方法など、テーマ内で Shopify 特有の様々なダイナミックデータにアクセスすることができます。

Liquid について詳しくはこちら

Ajax API

Ajax APIShopify のテーマで使用され、ブラウザを更新することなく購入者のショッピングカートを更新します。例としては、基本的な商品情報の取得、ショッピングカートへの商品の追加、カートの中身の消去などがあります。

Ajax API についての詳細はこちら


非推奨 API

非推奨の API は引き続き利用可能ですが、サポートされておらず、いつでも動作を停止する可能性があります。開発者の方は、できるだけ早くサポートされている他の API に移行してください。


REST Admin API にページネーションされたリクエストを作成

REST エンドポイントは、カーソルベースのページネーションをサポートします。このガイドでは、REST Admin API からページネーションされたデータを要求し、結果の各ページにアクセスする方法について説明します。

Note

カーソルベースのページネーションは、API のバージョン 2019 年 7 月以降でのみサポートされています。これは、以下にリストされているエンドポイントのページベースのページネーションに代わるものです。

使い方 | How it works

カーソルベースのページネーションをサポートする REST エンドポイントにリクエストを送信すると、レスポンスのボディは結果の最初のページを返し、レスポンスヘッダーは結果の次のページと前のページ(該当する場合)へのリンクを返します。応答ヘッダーのリンクを使用して、結果のページを反復処理できます。

リンクヘッダーは次の構文を使用します。

#...
Link: "<https://{shop}.myshopify.com/admin/api/{version}/products.json?page_info={page_info}&limit={limit}>; rel={next}, <https://{shop}.myshopify.com/admin/api/{version}/products.json?page_info={page_info}&limit={limit}>; rel={previous}"
#...

リンクヘッダーには、relation-typesがリンクされたページと結果の現在のページとの関係を説明するrelパラメーターが含まれています。値はpreviousまたはnextのどちらかです。最初のリクエストが結果の追加ページを生成するのに十分な記録を返さない場合、レスポンスにはリンクヘッダーがありません。

パラメータ | Parameters

リンクヘッダーの URL には、最大 3 つまでパラメーターを含めることができます

  • page_info:あるページの結果にアクセスするために使用される一意の ID です。page_infoパラメータを変更することはできません。またリンクヘッダーの URL に表示されているとおりに使用しなければなりません。
  • limit:ページに表示する結果の最大数です。
  • fields:結果に表示するフィールドのコンマ区切りのリスト。このパラメーターは、一部のエンドポイントでのみ使えます。

page_infoパラメータを含むリクエストには、limitfields(エンドポイントに適用される場合)以外の他のパラメータを含めることはできません。結果を他のパラメーターでフィルター処理する場合は、最初のリクエストにそれらのパラメーターを含める必要があります。

Note

pageパラメータを送信するリクエストはエラーを返します。

サポートされているエンドポイント | Supported endpoints

次のエンドポイントでカーソルベースのページネーションを使用できます。

2021 年 1 月リリース

2019 年 10 月リリース

2019 年 7 月リリース

Saved searches

  • ArticleSavedSearch
  • BalanceTransactionSavedSearch
  • BlogSavedSearch
  • CheckoutSavedSearch
  • CollectionSavedSearch
  • CommentSavedSearch
  • DiscountCodeSavedSearch
  • DraftOrderSavedSearch
  • FileSavedSearch
  • GiftCardSavedSearch
  • InventoryTransferSavedSearch
  • MetaTagsController
  • OrderSavedSearch
  • PageSavedSearch
  • PriceRuleSavedSearch
  • ProductSavedSearch
  • ProductVariantSavedSearch
  • RedirectSavedSearch
  • TransferSavedSearch

ページネーションされたリクエストを作成し、ページを繰り返し処理する

ページネーションされた結果をサポートするエンドポイントにリクエストを送信する場合、limitパラメータを使用して、ページごとに返す結果の数を設定できます。limitを指定しない場合、エンドポイントはデフォルトのページの制限を使用します。このリクエストで他のパラメータを設定して、結果を絞り込むこともできます。

次のリクエストの例では、1ページあたり3商品というlimitのもと、コレクションに属するすべての商品を商品エンドポイントに要求します。

Request

GET https://{shop}.myshopify.com/admin/api/2019-07/products.json?limit=3&collection_id=841564295

Response header

#...
Link: "<https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=hijgklmn&limit=3>; rel=next"
#...

Response body

{
  "products": [
    {id: 1 ... },
    {id: 2 ... },
    {id: 3 ... }
  ],
}

Response header は、次のページの URL を含むリンクヘッダーの結果を返します。Response body は、3 つの製品を含む最初のページの結果を返します。

次のページの結果を取得するには、最後のレスポンスのリンクヘッダーに保存されている URL にリクエストを送信します。

Request

GET https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=hijgklmn&limit=3

Note

URL にはpage_infoパラメータが含まれているため、limitを除いて他のパラメータをコールに追加することはできません。他のパラメータを含めると、リクエストが失敗する可能性があります。

Response header

#...
Link: "<https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=abcdefg&limit=3>; rel=previous, <https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=opqrstu&limit=3>; rel=next"
#...

Response body

{
  "products": [
    {id: 4 ... },
    {id: 5 ... },
    {id: 6 ... }
  ],
}

Response header には、前のページの結果へのリンクと次のページへのリンクが含まれています。Response body には、2 ページ目の結果が含まれ、最初のページの次の 3 つの製品が含まれます。

リンクヘッダーの URL を使用して、結果の各ページを反復処理できます。ページを呼び出し、Response header に前のページへのリンクのみが含まれている場合は、結果の最後のページに到達しています。

Note

リンクヘッダーの URL は一時的なものであり、後で使用するために保存することはお勧めしません。これらの URL は、それらを生成したリクエストを処理しているときにのみ使用してください。

特定のページの結果の数を変更する

リンクヘッダーの URL のlimitを変更して、指定したポイントから異なる数の結果を返すことができます。たとえば、次のリクエスト例では、limitパラメータ 3 を使用して、すべての製品の製品エンドポイントを要求しています。

Request

GET https://{shop}.myshopify.com/admin/api/2019-07/products.json?limit=3

Response header

{
  "products": [
    {id: 1 ... },
    {id: 2 ... },
    {id: 3 ... }
  ],
}

Response body

#...
Link: "<https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=hijgklmn&limit=3>; rel=next"
#...

リンクヘッダーの URL のlimitを 6 に変更し、その URL にリクエストを送信すると、Response body は最初のページの結果の後に 6 つの製品を返します。

Request

GET https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=hijgklmn&limit=6

Response header

2Link: "<https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=vwxyzab&limit=6>; rel=next"

Response body

{
  "products": [
    {id: 4 ... },
    {id: 5 ... },
    {id: 6 ... },
    {id: 7 ... },
    {id: 8 ... },
    {id: 9 ... }
  ],
}

GraphQL による結果のページング

接続を使ってリソースのリストを取得する際には、引数を使って取得する結果の数を指定します。カーソルベースのページネーションを使用すると、接続から取得する結果のセットを選択できます。

コネクションの概要

コネクションは、ノードのリストを取得します。ノードは、グローバル ID を持ち、Ordertype などのスキーマで定義された型を持つオブジェクトです。ノードはエッジによって接続されていると言われています。

例えば、orders 接続は、クエリルートと Order ノードをつなぐすべてのエッジを見つけ、要求されたデータを各ノードから返します。例えば、lineItems コネクションを使用して、orders コネクション内の各注文のラインアイテムを取得するように、他のコネクションの中にコネクションを入れ子にすることもできます。

注文のリストをページネーションするには、Order タイプには含まれていないデータを返す必要があります。このデータには、接続内にさらに多くの結果があるかどうか、どの注文が現在の結果に含まれているかなどが含まれます。ノードオブジェクトに含まれないフィールドを選択できるように、Shopify はすべての接続にedgesnodeレイヤーを含めています。

query {
  orders(first: 2) {
    edges {
      node {
        id
      }
    }
  }
}
{
  "data": {
    "orders": {
      "edges": [
        {
          "node": {
            "id": ...
          }
        },
        {
          "node": {
            "id": ...
          }
        }
      ]
    }
  }
}
  • edges - 接続の各エッジから取得するフィールドの選択に使用します。edges フィールドは、コネクション内の各エッジから選択されたフィールドを取得するため、for-loop に似ています。
  • node - 各エッジのノードから取得したいフィールドを選択するために使用します。
    コネクション、エッジ、ノードの各レベルでフィールドを指定すると、ページネーションに使用される pageInfocursor というフィールドを含めることができます。
query {
  orders(first: 10) {
    pageInfo {
      # 現在の検索結果のページに関する詳細を返します
      hasNextPage # このページの後にも結果があるかどうか
      hasPreviousPage # このページの前にも結果があるかどうかpage
    }
    edges {
      cursor # コネクション内のエッジの位置を示すマーカー
      node {
        name # 各ノードで返されるフィールド
      }
    }
  }
}

pageInfo フィールド

各接続は、2 つのフィールドを持つ PageInfo オブジェクトを返すことができます。

  • hasNextPage (Boolean!) - 現在のセグメントの後に、接続に結果があるかどうか。
  • hasPreviousPage (Boolean!) - 現在のセグメントの前に、接続内に結果があるかどうか。
    ページ情報は、各エッジではなく、クエリごとに一度だけ取得するので、接続レベルでは、edgesフィールドの横にpageInfoを含めます。

POST /admin/api/2021-07/graphql.json

query {
  products(first: 3) {
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
    edges {
      node {
        id
      }
    }
  }
}

JSON response

Copy
{
  "data": {
    "products": {
      "pageInfo": {
        "hasNextPage": true,
        "hasPreviousPage": false
      },
      "edges": [
        {
          "node": {
            "id": ...
          }
        },
        {
          "node": {
            "id": ...
          }
        },
        {
          "node": {
            "id": ...
          }
        }
      ]
    }
  },
  ...
}

カーソルフィールド

コネクション内の各エッジは、コネクション内のエッジの位置への参照であるカーソルを返すことができる。カーソルはnodeではなくエッジのプロパティであるため、エッジレベルではノードフィールドの横にcursorフィールドを含める。

query {
  orders(first: 10) {
    edges {
      cursor
      node {
        id
      }
    }
  }
}

エッジのカーソルを出発点にして、接続中の前後のノードを取り出すことができます。

カーソルベースのページネーション

クエリに pageInfo フィールドと cursor フィールドを含めることで、結果をページネーションすることができます。以下の例では、両方のフィールドを含み、クエリ変数を使用してその値を引数として渡しています。$orderNum 変数は必須であり、返す結果の数を指定するために使用します。$cursor 変数は必須ではありません。$cursor変数がない場合、afterの引数は無視されます。

POST /admin/api/2021-07/graphql.json

query ($numProducts: Int!, $cursor: String) {
  products(first: $numProducts, after: $cursor) {
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
    edges {
      cursor
      node {
        title
      }
    }
  }
}

変数

{
  "numProducts": 3
}

JSON レスポンス

{
  "data": {
    "products": {
      "pageInfo": {
        "hasNextPage": true,
        "hasPreviousPage": false
      },
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjoxMDA3OTc4ODg3NiwibGFzdF92YWx1ZSI6IjEwMDc5Nzg4ODc2In0=",
          "node": {
            "title": "The T-Shirt"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoxMDA3OTc5MzQyMCwibGFzdF92YWx1ZSI6IjEwMDc5NzkzNDIwIn0=",
          "node": {
            "title": "The Backpack"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoxMDA3OTc5NDM4MCwibGFzdF92YWx1ZSI6IjEwMDc5Nzk0MzgwIn0=",
          "node": {
            "title": "The Blouse"
          }
        }
      ]
    }
  },
  ...
}

このクエリは、接続の最初から 3 つの結果を返し、それらには各エッジのカーソルが含まれています。

次の例では、The Blouseのカーソルが接続結果の開始点として使用されています。この例では、接続のその時点以降の次の 3 つの結果を取得します。

POST /admin/api/2021-07/graphql.json

query ($numProducts: Int!, $cursor: String) {
  products(first: $numProducts, after: $cursor) {
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
    edges {
      cursor
      node {
        title
      }
    }
  }
}

変数

{
  "numProducts": 3,
  "cursor": "eyJsYXN0X2lkIjoxMDA3OTc5NTc4OCwibGFzdF92YWx1ZSI6IjEwMDc5Nzk1Nzg4In0="
}

JSON レスポンス

{
  "data": {
    "products": {
      "pageInfo": {
        "hasNextPage": true,
        "hasPreviousPage": true
      },
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjoxMDA3OTc5NjMwMCwibGFzdF92YWx1ZSI6IjEwMDc5Nzk2MzAwIn0=",
          "node": {
            "title": "The Shorts"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoxMDA3OTc5NjY4NCwibGFzdF92YWx1ZSI6IjEwMDc5Nzk2Njg0In0=",
          "node": {
            "title": "The Jumper"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoxMDA3OTc5NzE5NiwibGFzdF92YWx1ZSI6IjEwMDc5Nzk3MTk2In0=",
          "node": {
            "title": "The Sneakers"
          }
        }
      ]
    }
  },
  ...
}

Shopify API レート制限

プラットフォームがすべての人にとって安定して公平であるようにするために、すべての ShopifyAPI はレート制限されています。 レート制限を適用するために、さまざまな戦略を使用しています。 開発者には、呼び出しを制限し、結果をキャッシュし、責任を持ってリクエストを再試行するための業界標準の手法を使用するようお願いしています。

API によるレート制限の比較

Shopify API は、いくつかの異なるレート制限方法を使用します。 これらについては以下で詳しく説明しますが、簡単に説明すると次のようになります。

APIRate-limiting methodStanderd limitShopify Plus limit
Admin API(GraphQL)計算されたクエリコスト50 points/second100 points/second
Admin API(REST)リクエストベースの制限2 requests/second4 requests/second
Storefront API時間ベースの制限 リクエストごとに最低 0.5 秒、ユーザー IP ごとに 60 秒リクエストごとに最低 0.5 秒、ユーザー IP ごとに 120 秒
Payments Apps API (GraphQL)計算されたクエリコスト910 points/second1820 points/second

リーキーバケットアルゴリズム

すべての ShopifyAPI は、リーキーバケットアルゴリズムを使用してリクエストを管理します。 このアルゴリズムを使用すると、アプリは時間の経過とともにまれなバーストで無制限の量のリクエストを行うことができます。
リーキーバケットのメタファーについて理解するための主なポイントは次のとおりです。
- 各アプリはバケットにアクセスできます。 たとえば、60 個の「ビー玉」を保持できます。
- 毎秒、ビー玉がバケットから取り出されます(ある場合)。 そうすれば、常により多くの余地があります。
- 各 API リクエストでは、バケットにビー玉を投げる必要があります。
- バケットがいっぱいになると、エラーが発生し、バケットで空きができるまで待つ必要があります。
このモデルにより、API 呼び出しを責任を持って管理するアプリは、必要に応じてリクエストをバーストするためのスペースを常にバケットに確保できます。 たとえば、1 秒あたり平均 20 リクエスト(「ビー玉」)であるのに、突然 30 リクエストを一度に行う必要がある場合でも、レート制限に達することなくそれを行うことができます。

リーキーバケットアルゴリズムの基本原則は、それらを適用するために使用される特定の方法に関係なく、すべてのレート制限に適用されます。

レート制限方法

Shopify は、レート制限を管理するために 3 つの異なる方法を使用します。 API が異なれば、ユースケースに応じて使用するメソッドも異なるため、アプリで発生するさまざまな種類のレート制限を理解してください。

リクエストベースの制限

アプリは 1 分あたり最大数のリクエストを行うことができます。 例:60 秒以内に 40 の API リクエスト。 返されるデータの量に関係なく、各リクエストは等しくカウントされます。

このメソッドは、REST 管理 API によって使用されます。

時間ベースの制限

アプリは、1 分あたり最大の時間を要するリクエストを行うことができます。 例:60 秒以内に 120 のリクエストがあり、各リクエストが返されるまでに 0.5 秒かかります。 より複雑なリクエストは時間がかかるため、それに比例して制限の大きな部分を占めます。

このメソッドは、StorefrontAPI によって使用されます。

計算されたクエリコスト

アプリは、1 分あたり最大ポイント数のリクエストを行うことができます。 例:60 秒以内に 1000 ポイント。 より複雑なリクエストはより多くのポイントを消費するため、それに比例して制限の大きな部分を占めます。

このメソッドは GraphQLAPI によって使用されます。

GraphQL Admin API のレート制限

GraphQL Admin API の呼び出しは、計算されたクエリコストに基づいて制限されます。つまり、リクエストの数ではなく、時間の経過に伴うリクエストのコストを考慮する必要があります。

GraphQL Admin API のレート制限は、アプリとストアの組み合わせに基づいています。これは、同じストアであっても、あるアプリからの呼び出しが別のアプリのレート制限に影響を与えないことを意味します。同様に、あるストアへの呼び出しは、同じアプリからであっても、別のストアのレート制限に影響を与えません。

アプリとストアの各組み合わせには、1000 コストポイントのバケットが与えられ、リーク率は 1 秒あたり 50 コストポイントです。つまり、クエリの合計コストは常に 1,000 ポイントを超えることはできず、その部屋は 1 秒あたり 50 ポイントの割合でアプリのバケットに作成されます。よりシンプルで低コストのクエリを作成することで、時間の経過とともにより多くのクエリを作成できます。

制限では、要求されたクエリコストと実際のクエリコストの組み合わせが使用されます。実行を開始する前に、アプリのバケットには、クエリの要求されたコストに対して十分なスペースが必要です。実行が完了すると、要求されたコストとクエリの実際のコストの差額がバケットに払い戻されます。

計算コスト

スキーマのすべてのフィールドには、整数のコスト値が割り当てられています。 クエリのコストは、各フィールドのコストの合計です。 クエリの実行は、クエリの実際のコストを知るための最良の方法です。

デフォルトでは、フィールドのコストは、フィールドが返すものに基づいています。

Field returnsCost value
Scalar0
Enum0
Object1
Interface1
Union1
これらのデフォルトのコストは設定されていますが、Shopify はフィールドに手動のコストを設定する権利も留保します。

Note
ミューテーションのデフォルトのコストは10です。接続フィールドのコストは2に加えて、firstlastの引数を使用して要求されたオブジェクトの数です。

要求された実際のコスト

Shopify は、クエリ実行の前後の両方でクエリのコストを計算します。 要求されたコストは、要求されたフィールドの数に基づいています。 オブジェクトタイプフィールドが null を返すためにクエリが早期に終了したり、接続フィールドが要求されたよりも少ないエッジを返す可能性があるため、実際のコストは返された結果に基づいています。

単一クエリの制限

API への単一のクエリは 1,000 のコストを超えることはできません。 この制限は、クエリの要求されたコストに基づいてクエリが実行される前に適用されます。

入力配列の最大サイズ制限

配列を受け入れる入力引数の最大サイズは 250 です。入力配列が 250 項目を超えると、クエリとミューテーションはエラーを返します。

GraphQL のレスポンス

応答には、要求のコストとスロットルの状態に関する情報が含まれます。 このデータは、extensions key の下に返されます。

"extensions": {
    "cost": {
      "requestedQueryCost": 101,
      "actualQueryCost": 46,
      "throttleStatus": {
        "maximumAvailable": 1000,
        "currentlyAvailable": 954,
        "restoreRate": 50
      }
    }
  }

各フィールドが要求されたコストにどのように寄与するかについての詳細な内訳を取得するには、ヘッダー'X-GraphQL-Cost-Include-Fields':trueを要求に含めることができます。

"extensions": {
    "cost": {
      "requestedQueryCost": 101,
      "actualQueryCost": 46,
      "throttleStatus": ...,
      "fields": [
        {
          "path": [
            "shop"
          ],
          "definedCost": 1,
          "requestedTotalCost": 101,
          "requestedChildrenCost": 100
        },
        ...
      ]
    }
  }

一括操作

大量のデータをクエリしてフェッチするには、単一のクエリではなく一括操作を使用する必要があります。 一括操作は大量のデータを処理するように設計されており、単一のクエリにあるような最大コスト制限やレート制限はありません。

REST Admin API のレート制限

REST Admin API の呼び出しは、リクエストベースの制限によって管理されます。つまり、アプリが行う API 呼び出しの総数を考慮する必要があります。 さらに、リソースベースのレート制限とスロットルがあります。

REST Admin API のレート制限は、アプリとストアの組み合わせに基づいています。 これは、同じストアであっても、あるアプリからの呼び出しが別のアプリのレート制限に影響を与えないことを意味します。 同様に、あるストアへの呼び出しは、同じアプリからであっても、別のストアのレート制限に影響を与えません。

制限は、漏出バケットアルゴリズムを使用して計算されます。 レート制限を超えた後に行われたすべてのリクエストは抑制され、HTTP 429 Too ManyRequestsエラーが返されます。 十分な数のリクエストがバケットから空になった後、リクエストは再び成功します。 レート制限ヘッダーを使用すると、ストアのスロットルの現在の状態を確認できます。

バケットサイズとリークレートのプロパティによって、API のバースト動作とリクエストレートが決まります。

デフォルト設定は次のとおりです。

  • Bucket size: 40 requests/app/store
  • Leak rate: 2/second

Shopify Plus
ShopifyPlus ストアの bucket size と leak rate は 2 倍になります。

  • Bucket size: 80 requests/app/store
  • Leak rate: 4/second

バケットサイズを超えると、HTTP 429 Too ManyRequestsエラーが返されます。 バケットは、1 秒あたり 2 リクエストのリークレートで空になります。 スロットルを回避するために、1 秒あたり平均 2 つのリクエストを実行するようにアプリを構築できます。 スロットルは合格または不合格の操作です。 バケットに使用可能な容量がある場合、要求はキューイングまたは処理の遅延なしに実行されます。 それ以外の場合、要求は抑制されます。

GET リクエストには追加のレート制限があります。 pageパラメータの値が、要求されたリソースの 100,000 を超えるオフセットになると、429 Too ManyRequestsエラーが返されます。 たとえば、GET /admin/collects.json?limit=250&page=401へのリクエストは、100,250(250 x 401 = 100,250)のオフセットを生成し、429 応答を返します。
alert
Caution
ページベースのページネーションは、バージョン 2019-07 の AdminAPI で非推奨になりました。 代わりに、カーソルベースのページ付けを使用してください。

ヘッダーのレート制限

API リクエストに応答して送信された ShopifyX-Shopify-Shop-Api-Call-Limitヘッダーを使用して、すでに行ったリクエストの数を確認できます。 このヘッダーには、特定のストアに対して行ったリクエストの数が一覧表示されます。 例えば:

X-Shopify-Shop-Api-Call-Limit: 32/40

この例では、32が現在のリクエスト数で、40がバケットサイズです。 リクエスト数は、時間の経過とともにリーク率に応じて減少します。 たとえば、ヘッダーに39/40リクエストが表示されている場合、10 秒の待機期間の後、ヘッダーには19/40リクエストが表示されます。

Retry-After ヘッダー

リクエストがレート制限を超えると、429 Too ManyRequestsエラーとRetry-Afterヘッダーが返されます。 Retry-Afterヘッダーには、再度リクエストできるようになるまで待機する秒数が含まれています。 待機時間が経過する前に行われた要求はすべて抑制されます。

X-Shopify-Shop-Api-Call-Limit: 40/40
  Retry-After: 2.0

ストアフロント API のレート制限

Storefront API の呼び出しは、時間ベースの制限によって管理されます。つまり、リクエストの数ではなく、リクエストが完了するまでにかかる時間を考慮する必要があります。

バケットサイズとリークレートのプロパティによって、API のバースト動作とリクエストレートが決まります。 60 秒の制限は、アプリがインストールされているストアの ID ではなく、アプリを操作する購入者の IP アドレスに適用されます。 これは、販売者のストアでの購入者のトラフィックの増加によってアプリが抑制されないことを意味します。

デフォルト設定は次のとおりです。

  • Bucket size: 60 seconds/app/IP address
  • Leak rate: 1/second

Shopify Plus
Shopify Plus ストアの bucket size は二倍の 120 秒です。

Storefront API へのすべてのリクエストの実行には、最低 0.5 秒かかります。 リクエストが完了すると、合計経過時間が計算され、バケットから差し引かれます。

バケット制限の例

ユーザーがアプリを読み込んだときに、クライアントが複数の並列 API リクエストを行うとします。

  • それぞれ 0.5 秒以下かかる 20 の簡単なクエリ
  • それぞれ 1 秒かかる 15 のより複雑なクエリ
  • それぞれ 2 秒かかる 10 個の非常に複雑なクエリ
    総コストは次のようになります:(20⨉0.5)+(15⨉1.0)+(10⨉2.0)= 45 秒。

このシナリオでは、15 秒分のクエリを引き続き使用できます。

チェックアウトレベルのスロットル

Shopify は、StorefrontAPI で 1 分あたりに作成できるチェックアウトの量を制限します。 API クライアントがこのスロットルを超えると、200 Throttledエラー応答が返されます。 Shopify は、このシナリオに対応できるようにアプリを設計することをお勧めします。 たとえば、指数バックオフアルゴリズムを使用してリクエストキューを実装できます。

入力配列の最大サイズ制限

配列を受け入れる入力引数の最大サイズは 250 です。入力配列が 250 項目を超えると、クエリとミューテーションはエラーを返します。

リソースベースのレート制限

次の管理 API リソースには、GraphQL バージョンと REST バージョンの両方で、ストアに 50,000 の製品バリアントがある場合に有効になる追加のスロットルがあります。 このしきい値に達すると、1 日あたり 1,000 を超える新しいバリアントを作成できなくなります。

場合によっては、Shopify はプラットフォームの乱用を防ぐためにレート制限を実施する必要があります。 したがって、アプリは、ここにリストされているエンドポイントだけでなく、すべてのエンドポイントでレート制限を処理できるように準備する必要があります。

Shopify Plus
これらの追加の制限は、ShopifyPlusプランのストアには適用されません。

GraphQL のミューテーション

REST エンドポイント

アプリが特定のリソースの API レート制限に達すると、429 Too Many Requests 応答と、スロットルが適用されたというメッセージを受け取ります。

レート制限エラーの回避

ベストプラクティスを念頭に置いてアプリを設計することは、スロットルエラーを回避するための最良の方法です。 たとえば、列内の API リクエストをずらして、次の列に入れられた仕事が実行されるのを待っている間に他の処理タスクを実行できます。 アプリを設計するときは、次のベストプラクティスを考慮してください。

  • アプリに必要なデータのみを取得するようにコードを最適化します。
  • アプリが頻繁に使用するデータにはキャッシュを使用します。
  • よりスムーズな配布を求めるリクエストの割合を調整します。
  • エラーをキャッチするコードを含めます。 これらのエラーを無視してリクエストを続けようとすると、アプリは正常に回復できなくなります。
  • すべての API 応答に含まれる、アプリの API 使用状況に関するメタデータを使用して、アプリの動作を動的に管理します。
  • 再試行するのに十分な時間が経過するまで、コードは追加の API リクエストの作成を停止する必要があります。 推奨されるバックオフ時間は 1 秒です。

Shopify API レスポンスステータスとエラーコード

Shopify が API エンドポイントへのリクエストを受信すると、元のリクエストに応じて、いくつかの異なる HTTP ステータスコードがレスポンスで返されます。

ステータスコード 意味
200 OKリクエストは Shopify によって正常に処理されました。
201 Createdリクエストは達成され、新しいリソースが作成されました。
202 Acceptedリクエストは受理されましたが、まだ処理されていません。
303 See Otherリクエストに対するレスポンスは Location ヘッダーの別の URL にあり、そのリソースに対して GET メソッドを使って取得できます。
400 Bad Requestリクエストがサーバーに理解されませんでした。一般的には、構文が間違っているか、Content-Type ヘッダーが正しく application/json に設定されていないことが原因です。 このステータスは、OAuth トークンの交換プロセスにおいて、リクエストが無効なcodeパラメータを提供した場合にも返されます。
401 Unauthorized必要な認証情報がリクエストに含まれていないか、間違っています。
402 Payment Requiredリクエストされたショップは現在凍結されています。凍結を解除するには、ショップオーナーがショップの管理画面にログインし、未払い金を支払う必要があります。
403 Forbiddenサーバーがリクエストへの応答を拒否しています。これは一般的に、このアクションに対して適切なスコープを要求していないためです。
404 Not Found要求されたリソースは見つかりませんでしたが、将来的に再び利用可能になる可能性があります。
406 Not Acceptable要求されたリソースは、リクエストで送信された Accept ヘッダによれば、受け入れられないコンテンツを生成することしかできません。
422 Unprocessable Entityリクエストボディは正しく形成されていますが、セマンティックエラーが含まれています。422 のエラーコードは、以下のような様々な状況で返される可能性がありますが、これらに限定されるものではありません。
・誤ってフォーマットされた入力
・在庫切れの商品をチェックアウトする
・フルフィルメントのある注文のキャンセル
・ラインアイテムとオーダーの両方にタックスラインがあるオーダーの作成
・電子メールや名前のない顧客の作成
・タイトルのない商品の作成
レスポンスボディには、errorserrorパラメーターの詳細が記載されています。
423 Locked要求されたショップは現在ロックされています。ショップがロックされるのは、API リクエストの制限を繰り返し超えた場合や、アカウントの侵害や詐欺のリスクが検出されるなど、アカウントに問題がある場合です。ショップがロックされている場合は、サポートにお問い合わせください。
429 Too Many Requestsアプリケーションがレート制限を超えたため、リクエストが受け入れられませんでした。Shopify の API レートリミットについてはこちらをご覧ください。
500 Internal Server ErrorShopify で内部エラーが発生しました。Shopify のスタッフが調査できるように、Shopify APIs and SDKs フォーラムに投稿してください。
501 Not Implemented要求されたエンドポイントはそのショップでは利用できません。例えば、Shopify Plus 専用の API へのアクセスを非 Plus のショップに要求した場合などです。このレスポンスは、このエンドポイントが将来の使用のために予約されていることを示す場合もあります。
503 Service Unavailableサーバーは現在利用できません。Shopify のステータスページでサービス停止の報告を確認してください。
504 Gateway Timeoutリクエストは時間内に完了できませんでした。Shopify は応答を最大 10 秒間待ちます。複数の小さなリクエストに分けてみてください。

ShopifyAPI 検索構文

このページでは、テキストフィールドを検索するための構文について説明します。

検索機能のインターフェースとして、Shopify 全体で同じ検索クエリ構文が使用されています。これには、storefront,admin, mobile apps, customer group queries, Admin API, Storefront APIが含まれます。API の場合、クエリできる特定のリソースはリファレンスドキュメントで定義されています。

Note
Admin API は/search.jsonCustomerおよびGiftCardリソースのパスをサポートします。


検索クエリ文法の概要

文字列クエリは、用語、連結語、修飾子、および比較対象で構成されるテキスト検索です。ここで定義されている検索文法規則は、検索クエリ構文で定義されているように、より大きな構造に組み込むことができます。

検索文法はEBNFと同様に表現され、次のようにいくつかのベースライン終端記号を使用します。

アイテム説明
whitespaceスペース、タブ、または改行文字の任意のシーケンス。
name非空白、非特殊文字の任意のシーケンス。詳細については、特殊文字を参照してください。
value任意の名前、または引用符で囲まれた文字列(一重引用符または二重引用符の両方が許可されます)。

クエリ

文法のルートはクエリです。

Query = Term { [ whitespace Connective ] whitespace Term }

クエリは、空白で区切られ、任意の単一の連結語で区切られた 1 つ以上の用語です。クエリには、選択的に先頭と末尾に空白を入れることができます。
query=John Smith

連結語

Connective = "AND" | "OR"

接続詞が 2 つの用語の間に指定されていない場合、ANDが暗示的に指定されます。
query=state:enabled OR state:disabled

条項

Term = [ Modifier ] ( "(" Query ")" | [ name Comparator ] value )

用語は、任意の修飾子と、それに続くサブクエリ(括弧で囲まれた)または任意の名前とコンパレータを含む値で構成されます。
query=-first_name:Bob AND orders_count:>3 orders_count:<=4

修飾子

Modifier = "-" | "NOT" whitespace

修飾子は「-」(この場合は空白を続けてはいけません)または「NOT」(この場合は空白を続けてください)にすることができます。どちらも同じ意味です。
query=-first_name:Bob

コンパレータ

Comparator = ":" | ":<" | ":>" | ":<=" | ":>="

コンパレータの現在のリストは次のとおりです。

  • : 同等性を持つ
  • :< より少ない
  • :> より大きい
  • :<= 以下である
  • :>= 以上である

*同等性は、フィールドのインデックス付け方法によって異なります。数値フィールドの場合、:は等しいことを表します。トークン化されたフィールドの場合、用語がフィールドのどこかにあると、同等性が存在します。トークン化されていないフィールドの場合、検索クエリ文字列は検索されたフィールドと正確に一致する必要があります。


検索クエリの構文

Shopify の検索クエリ構文は、定義された文法に基づいており、次の検索動作を可能にします。

用語検索

用語検索では、大文字と小文字を区別しない検索がドキュメントの任意のフィールドに表示されます。
query=Bob Norman
これにより、「bob」と「norman」の両方で大文字と小文字を区別しない検索が行われます。

フィールド検索

フィールド検索は、特定のフィールドの用語に適用されます。
query=first_name:Bob age:27
これにより、「first_name」フィールドで「Bob」が検索され、「age」フィールドで「27」が検索されます。値は空白なしでフィールドの直後に続く必要があります:first_name: Bobは実際には「first_name」および「Bob」という用語を検索します。

範囲検索

範囲検索は、検索する値の範囲を指定します。
query=orders_count:>16 orders_count:<=30
ここで文書にマッチするorders_countフィールドは 16 より大きく 30 以下です。サポートされている演算子は>>=<<=です。

等しいとするには、orders_count:=16ではなくorders_count:16とします。前者は実際にはorders_countフィールドで「=16」を検索します。

Not クエリ

このクエリは、NOT 演算子を含むドキュメントを除外します。
query=-bob
query=NOT bob
これらのクエリはどちらも、「bob」という用語を含むドキュメントを返しません。

Not クエリを実行するには、「NOT」演算子を大文字にする必要があり、次のスペースで区切られた用語またはクエリにのみ適用されます。マイナス記号は、フィールド、値、またはサブクエリの前に置く必要があります。-field:value -value -(subquery)

boolean 演算子

boolean 演算子を使用すると、論理演算子を使用して用語を組み合わせることができます。
query=bob OR norman AND Shopify
これは、"Shopify "という用語を持たなければならず、"bob "または "norman "という用語の少なくとも 1 つを持つべきである文書を検索します。
query=bob OR norman Shopify
OR は AND よりも演算子の優先順位が高いため、このクエリは上記のクエリと同等です。さらに、用語またはクエリ間のデフォルトのブール演算子は AND であるため、明示的な AND 演算子は必要ありません。

グループ化

Shopify は、括弧を使用して句をグループ化し、サブクエリを形成することをサポートしています。
query=state:disabled AND ("sale shopper" OR VIP)
これは、タグsale shopperまたはVIPを使用して障害のある顧客を検索します。

フレーズクエリ

フレーズは、二重引用符で囲まれた単語のグループです。
query=first_name:"Bob Norman"
これにより、「first_name」フィールドで「bob」の直後に「norman」が続く用語が検索されます。フレーズクエリは、「Bob Norman」など、フィールドクエリの外部で使用できます。

プレフィックスクエリ

プレフィックスクエリは、指定された文字セットで始まる用語を含むドキュメントに一致します。
query=norm*
これにより、接頭辞「norm」で始まるすべての用語が検索されます。例、「norman」。

特殊文字

Shopify は、バックスラッシュエスケープを使用して特殊文字をエスケープする機能をサポートしています。特殊文字の現在のリストは次のとおりです。

: \ ( )

名前は-,',"の文字を含むことができますが、それらで始めることはできません。名前には、バックスラッシュエスケープを使用してエスケープされた文字を含めることができます。

Exists クエリ

Exists クエリは、指定されたフィールドに NULL 以外の値を持つドキュメントと一致します。
query=published_at:*
このクエリを NotQuery と組み合わせて、値が欠落しているフィールドを見つけることができます。例、-published_at:*

Shopify APi のバージョン管理 | Shopify API versioning

API のバージョン管理により、Shopify がプラットフォームを継続的に進化させながら、サードパーティの開発者に機能アップグレードと非推奨の予測可能なパスを提供することを可能にします。

今後の API の変更を確実に知るために、Changelogに従ってください。また、Partner Dashboard で常に連絡先を最新に保つようにしてください。


バージョン管理された API とバージョン管理されていない API | Versioned vs. unversioned APIs

バージョン管理された APIバージョン管理されていない API
Admin API (GraphQL および REST)
Storefront API
Webhooks
開発者プレビュー
OAuth endpoints (AccessScope を含む)
Liquid
Shopify Scripts
Ajax API
Analytics API
・その他、明示的にバージョン指定されていないリソース

リリーススケジュール | Release schedule

Shopify は 3 ヶ月ごとに、四半期の初めに新しい API バージョンをリリースします。バージョン名は、意味的に曖昧にならないように、日付をベースにしています(例:2020-01)。以下は、2020 年のリリーススケジュールの例:

安定したバージョン公開日いつまで安定したバージョンがサポートされているか
2021-012021 年 1 月 1 日2022 年 1 月 1 日
2021-042021 年 4 月 1 日2022 年 4 月 1 日
2021-072021 年 7 月 1 日2022 年 7 月 1 日
2021-102021 年 8 月 1 日2022 年 8 月 1 日

安定版は午後 5 時(UTC)にリリースされます。

各安定版のサポート期間は最低でも 12 ヶ月間です。つまり、連続する 2 つの安定版の間には、少なくとも 9 か月の重複期間があります。新しい安定版が導入され、お客様のアプリケーションに影響する変更が含まれている場合、前のバージョンのサポートが終了する前に、9 か月間、お客様のアプリケーションをテストし、新しいバージョンに移行することができます。

ヒント

新バージョンが、オンラインストアや Shopify 管理画面の UI など、API 以外にも影響を与える場合は、開発者プレビューが Partner Dashboard で公開されます。詳しくは、開発者プレビューをご覧ください。

私たちは、四半期ごとに最新の安定版 API を呼び出すようにアプリを更新することを強くお勧めします。しかし、もしお客様のアプリがサポートされなくなった安定版を呼び出した場合、Shopify は前倒しして、サポートされている最も古い安定版と同じ動作でリクエストに応答します。例えば、Shopify が2019-07を削除した場合、バージョン2019-07を呼び出した API リクエストは、バージョン2019-10が提供されます。

リクエストにバージョンが含まれていない場合は、API もサポートされている最も古い安定版をデフォルトとします。しかし、非推奨の変更を採用する際に、この動作に依存することはお勧めできません。アプリを更新する際には、リクエストごとに API のバージョンを指定する必要があります。アプリのバージョンを意識することで、サポートされている期間中は同じ動作をすることが保証されている特定の機能のセットにコードを固定することができます。

バージョン対応スケジュールの例


API バージョンの呼び出し | Calling an API version

Shopify API のバージョンは、アプリが呼び出す URL で明示的に宣言されます:

  • REST Admin API の URL:/admin/api/{ バージョン }/{ エンドポイント }.json

  • GraphQL Admin API の URL:/admin/api/{ バージョン }/graphql.json

  • Storefront API の URL:/api/{ バージョン }/graphql.json

例えば、以下の URL では、バージョン2021-07を呼び出しています:

  • Rest Admin API の URL。/admin/api/2021-07/products.json

  • GraphQL Admin API の URL:/admin/api/2021-07/graphql.json

  • Storefront API の URL:/api/2021-07/graphql.json

API にはいくつかの対応バージョンがあり、URL にバージョン名を代入することで、使用するバージョンを指定します。API のバージョンには、安定版(stable)、リリース候補版(release candidate)、不安定版(unstable)の 3 種類があります。

Shopify の API レスポンスには、X-Shopify-API-Versionというヘッダーが含まれており、リクエストの実行に使用された API バージョンが返されます。アプリを更新した場合、これはリクエストで指定された API バージョンと一致します。返されたバージョンが異なる場合は、アプリが古く、デフォルトの API バージョンを使用していることになります。

備考

Admin API を使用して、Ruby、Python、または Node でアプリケーションを作成している場合は、公式ライブラリを使用して Admin API と対話し、API バージョンを簡単に設定できます。

さらに、Storefront SDK のいずれかを使用している場合は、新しくリリースされた SDK ごとに API のバージョンが設定されることに注意してください。各 SDK のバージョンでサポートされている API のバージョンを確認するには、その SDK のバージョンのリリースノートを参照してください。

注:Webhook もバージョン管理されています。Webhook の API バージョンを選択する方法については、Versioned webhooksを参照してください。


リリース候補 | Release candidates

リリース候補では、次の安定版でリリースが予定されている変更点を確認できるため、できるだけ早くアプリのアップデートを開始することができます。API のリリース候補は、安定版のリリースと同じ日に公開されます。例えば、2020 年 1 月 1 日にバージョン2020-01がリリースされると、バージョン2020-04のリリース候補も利用可能になります。

下位互換性のある変更と下位互換性のある変更の両方をリリース候補に追加することで、安定版のリリースよりも先に利用できるようになります。このような理由から、本番環境ではリリース候補を使用しないことをお勧めします。


不安定な API のバージョン | Unstable API versions

API には常に不安定版が用意されています。不安定版には、まだ進行中の機能や変更が含まれており、定期的に後方互換性のある変更や下位互換性のある変更を行います。通常、変更点は安定版のリリース前に不安定版に掲載されますが、不安定版の変更点が最終的にリリースされることを保証するものではありません。ある機能が不安定版に追加されても、後に削除されるかもしれません。

不安定版の API は、新しい変更や機能を早期にテストするために使用することができますが、本番環境では使用しないようにしてください。

  • REST Admin API コールの例: https://{shop}.myshopify.com/admin/api/unstable/products.json

  • GraphQL Admin API コールの例: https://{shop}.myshopify.com/admin/api/unstable/graphql.json

  • Storefront API コールの例: https://{shop}.myshopify.com/api/unstable/graphql.json


非推奨プラクティス | Deprecaution practices

Shopify API の一部は、不要になったり、安全でなくなったり、古くなったりすると非推奨になります。API の新しいバージョンで削除されると、非推奨としてマークされます。非推奨は、API の以前の安定したバージョンに遡って適用されます。非推奨事項が導入された場合、その詳細や関連する移行情報は開発者の変更履歴で発表されます。

各バージョンのサポート期間は最低 1 年であるため、バージョン間には常に最低 9 カ月の重複期間があり、アプリを非推奨に対応させることができます。

非推奨のリソースを使用するアプリ

アップグレード期限後も公開アプリや販売チャネルがサポートされていないリソースを使用している場合は、Shopify App Store から上場廃止となります。また、サポートされていない公開アプリ、サポートされていないカスタムアプリ、またはサポートされていない販売チャネルをインストールしたマーチャントには、インストールプロセス中に警告が表示されます。

アプリがサポートされていない API リソースを使用し続けた場合、マーチャントは最低 7 日間、アプリのインストールがブロックされます。

Shopify の管理画面では、マーチャントにはアプリがサポートされていないことを示す警告メッセージが表示されます。これらの警告は、アップグレード期限後にアプリがサポートされていないリソースへの呼び出しを行った場合にのみ、マーチャントに表示されます。警告は、サポートされていないリソースの最後の使用が検出されてから 7 日後に削除されます。警告は、お客様またはマーチャントが手動で削除することはできません。

alert
注意

デスクトップアプリやモバイルアプリなど、アップデートが必要なスタンドアロンアプリで Shopify API を使用している場合、ユーザーはアプリが継続して動作することを保証するために、アップグレード期限前にアップデートする必要があります。これは、マーチャントがアプリをアップデートする時間を確保するために、移行期限よりもかなり前にアップデートしなければならないことを意味するかもしれません。サポートされていないリソースを呼び出すと、アプリが上場廃止になったり、マーチャントがアプリのインストールについて警告を受けたり、ブロックされたりする可能性があります。

GraphQL API の非推奨プラクティス

Shopify が GraphQL API のフィールドを非推奨にする場合、その変更は以下の内のいくつかの方法で伝えられます。

  • API ヘルスレポートに、変更が必要なリソースがリストアップされます。

  • Shopify's GraphQL Explorerなどの API クライアントツールに、そのフィールドの非推奨の警告が表示されます:

  • 開発者用の変更履歴に、非推奨となったことの通知が掲載されています。

  • API リファレンスが更新され、非推奨のフィールドと適用可能な代替手段が特定されます。

  • お客様のアプリに影響を与えるような下位互換性のない変更が差し迫っている場合は、お客様のアプリの開発者の緊急連絡先に非推奨について連絡することがあります。

REST API の非推奨プラクティス

Shopify が REST Admin API のリソースやリソースのプロパティを非推奨にした場合、その変更は以下の 1 つ以上の方法で通知されます。

  • API ヘルスレポートには、変更が必要なリソースの一覧が表示されます。

  • 非推奨の動作を含むコールは、レスポンスヘッダ X-Shopify-API-Deprecated-Reason と詳細情報を得るためのリンクを返します:

...
X-Shopify-Shop-Api-Call-Limit → 1/40
X-Shopify-API-Version → 2021-07
X-Shopify-API-Deprecated-Reason → https://help.shopify.com/tutorials/update-your-app-to-a-new-api-version/2019-07#foobar-endpoint-is-removed
...

備考

リソース上の個々のプロパティが非推奨である場合、そのリソースへの GET リクエストは、レスポンスに非推奨ヘッダを返しません。

  • 開発者用の変更履歴に、非推奨に関する通知が掲載されています。

  • REST Admin API リファレンスが更新され、影響を受けるリソースと必要なアクションが特定されます。

  • お客様のアプリに影響する下位互換性のない変更が差し迫っている場合、お客様のアプリの開発者の緊急連絡先に非推奨について連絡が行く場合があります。


Webhooks

Webhook のペイロードは、API レスポンスのペイロードと同様に、API のバージョン間で変更することができます。Webhook に使用する API バージョンを選択することができ、そのバージョンはアプリに送信されるすべての Webhook に使用されます。

選択した API バージョンがサポートされなくなると、Shopify は次にサポートされる安定バージョンの使用に移行します。Webhook は、Webhook の生成に使用された API バージョンを示すX-Shopify-API-Versionリクエストヘッダを含みます。この値が選択したバージョンと異なる場合は、選択した API バージョンはサポートされなくなります。

より新しい API バージョンの Webhook の変更によってアプリが影響を受ける場合は、選択した API バージョンのサポートが終了する前にアプリを更新する必要があります。

Webhook のバージョン管理についてはこちらをご覧ください。


技術的なアップデートの取得 | Getting technical updates

Shopify の管理画面からプライベートアプリを作成する場合、またはパートナーアカウントをお持ちの場合は、緊急時の開発者の連絡先を提供する必要があります。Shopify はこれらの情報を収集し、Shopify アプリを管理している開発者に重要な技術情報を伝えるために使用しています。この記事は、これらのアップデートを誰が受け取るべきかを決定するのに役立ち、これらの連絡から何を予測すべきかを説明します。

いつ Shopify から連絡がありますか? | When will Shopify contact you?

開発者の連絡先は、お客様のアプリが使用している API バージョンの下位互換性のない変更や、かなりの数のマーチャントに影響を与えるバグや障害についてお知らせするために必要です。以下は、当社がお客様に連絡する可能性のある状況です。

  • お客様のアプリに直接影響する API の変更を計画している。

  • お客様のアプリが非推奨のエンドポイントを使用しており、アプリの機能やマーチャント体験に影響を与えている可能性があります。

  • お客様のアプリにバグがあるか、マーチャントのストアに影響を与えるような障害が発生している。

これらの状況では、私たちの主要な連絡手段は電子メールです。2 番目と 3 番目の状況では、できるだけ早く問題を解決するために、開発者の連絡先電話番号を使ってお客様に連絡することもあります。


開発者の連絡先は誰にすればいいですか? | Who should be your developer contact?

パートナーの皆様には、開発者の連絡先として、定期的に受信ボックスを監視する個人やチームをお勧めします。これらの連絡は、Shopify の API と相互作用するアプリを管理する責任のある開発者を対象としており、Shopify API のバージョン管理に精通した技術的な聴衆にとって有用な情報を提供しています。

もしあなたがマーチャントで、開発者に代わってアプリをセットアップしているのであれば、開発者に最適な連絡先を聞くべきです。この記事に誘導することで、より多くの情報を提供することができます。


開発者連絡先の更新 | Update your developer contact details

開発者の連絡先を更新するプロセスは、公開アプリ、カスタムアプリ、プライベートアプリ、またはパートナー組織のために更新するのかによって異なります。

API の連絡先メールアドレスの更新

お客様の公開アプリやカスタムアプリが後方互換性のない変更が加えられた API バージョンを使用している場合、Shopify はお客様のアプリのセットアップページに記載されているメールアドレスに連絡します。

  1. Partner Dashboardにログインします。

  2. アプリ管理 に移動します。

  3. 更新したいアプリの名前をクリックします。

  4. アプリ情報 セクションに、API 連絡先メールアドレスを入力します。

  5. Save をクリックします。

プライベートアプリの連絡先の更新

  1. Shopify の管理画面から、アプリ管理に進みます。

  2. プライベートアプリを管理する をクリックします。

  3. 更新したいアプリの名前をクリックします。

  4. アプリ詳細 セクションで、緊急連絡用開発者メールアドレスを入力します。

  5. Save をクリックします。

パートナー組織の連絡先の更新

  1. Partner Dashboardにログインします。

  2. 設定 に進みます。

  3. 緊急連絡用の開発者連絡先 セクションで、緊急連絡用開発者メールと電話番号を入力します。

  4. Save をクリックします。



API ヘルスレポート | API health report

Shopify API の機能が非推奨になった場合、影響を受けるアプリを更新して、それらを使用するマーチャントのために引き続き動作することを確認する必要があります。公開アプリとカスタムアプリのそれぞれについて、API ヘルスレポートを見ることができます。このレポートには、アプリが行っている非推奨の呼び出しと、アプリ内のこれらの呼び出しを更新する期限が表示されます。

API ヘルスレポートをチェックするだけでなく、開発者の変更履歴を追うことで、アプリに影響を与える可能性のある変更点を確認することができます。アプリの更新方法については、バージョン管理ガイドで詳しく説明しています。


アプリのヘルスレポートを見る | View an app's health report

  1. Partner Dashboardにログインします。

  2. アプリ管理 をクリックします。

  3. API ヘルス の列にあるアプリのステータスインジケータをクリックします。

API ヘルスレポートには、アプリのステータスと、過去 30 日間にアプリが行った非推奨の API コールのリストが表示されます。リスト内の廃止されたコールには、アプリをアップデートするために必要な追加情報が表示されます。


API ヘルスステータス | API health statues

API ヘルスステータスは、過去 30 日間にアプリのアクセストークンを使用して行われたコールを反映します。アプリのステータスは以下のいずれかです:

  • OK:アプリは過去 30 日間に非推奨の API コールを行っていません。

  • Fix by (日付):アプリは、特定の日付までに更新しなければならない非推奨の API コールを行っています。このステータスには、黄色または赤色のインジケータが表示されます。

    • 黄色のインジケータは、アプリを更新するための期間が 30 日~ 9 ヶ月であることを意味します。

    • 黄色のインジケータは、アプリを更新するまでの期間が 30 日以上 9 ヶ月未満であることを意味します。

  • Fix overdue:アプリがサポートされていない API バージョンへの API コールを行っており、このアプリがインストールされている店舗で重大な問題を引き起こしている可能性があります。

アクセストークンは API の健全性に影響するため、アプリのアクセストークンをアプリ以外で使用しないようにしましょう。非推奨の API コールがあると、アプリのステータスが変わります。例えば、サポートチームの Postman や Insomnia のコレクションは、Fix byFix overdueのステータスを引き起こす可能性があります。

alert
注意

お客様のアプリがFix overdueとマークされ、非推奨 API コールの更新期限以降もサポートされていない API を呼び出し続けている場合、Shopify はアクションを取る権利を有します。アクションには、Shopify App Store からのアプリの削除、新規インストールのブロック、アプリが動作しないことをマーチャントに通知、またはマーチャントに代替アプリの推奨を提供することが含まれます。Fix overdueとマークされたアプリが、リストから削除されたり、インストールがブロックされたりする危険性がある場合は、API ヘルスレポートに通知が表示され、メールが届きます。

アップデートアプリのステータス確認

アプリをアップデートしてすべての非推奨コールを削除した後、アプリのステータスは API ヘルスレポートのFix by (日付) として最大 30 日間維持されます。

アプリのステータスは、アプリが最後に非推奨のコールを行ってから 30 日後に変更されます。更新期限まで 30 日を切っている場合、アプリのステータスは更新期限の翌日に変更されます。

30 日または更新期限が経過すると、アプリのステータスはOKに変わります。最後の非推奨コールの時刻は、Partner Dashboard のアプリ管理ページにあるアプリのステータスインジケータの下に表示されます。

API ヘルスレポートをフィルタリングすることで、アプリが非推奨のコールを行わなくなったことを確認できます。

  1. Partner Dashboard にログインします。

  2. アプリ管理をクリックします。

  3. API ヘルス列のアプリのステータスインジケータをクリックします。

  4. 最終日をクリックすると、アプリが過去 24 時間以内に行ったサポートされていないコールが表示されます。

レポートが空になるか、サポートされていないリソースが表示されなくなった場合は、アプリが更新されています。アプリのステータスは、30 日後に自動的にOKに変更されます。

備考

API ヘルスレポートに記載されている廃止された変更の影響を受けていないアプリの場合でも、すべてのコールについて、API ヘルスレポートに記載されている指定の API バージョン以降にアップデートする必要があります。


Webhook の非推奨事項の修正 | Fixing webhook deprecations

アプリで非推奨の webhook を修正したにもかかわらず、API ヘルスレポートに非推奨の webhook が表示されている場合は、Partner Dashboard でアプリのwebhook API バージョンを手動でアップグレードしたかどうかを確認してください。


プライベートアプリのバージョン管理 | Private app versioning

公開アプリやカスタムアプリと同様に、プライベートアプリでも、サポートされている API のバージョンを最新に保つために、時々アップデートが必要になることがあります。


自分のプライベートアプリが影響を受けているかどうかを知るにはどうすればいいですか?

プライベートアプリが非推奨コールを行っている場合は、いくつかの方法で通知を受け取ることができます。

バナー

管理画面のアプリ管理ページには、プライベートアプリが動作しなくなる可能性があることを警告するバナーが表示されています。どのアプリが危険なのかを確認するには、View private appsリンクをクリックします。

管理者のプライベートアプリのページには、現在非推奨の呼び出しを行っているプライベートアプリと、そのリクエストの移行期限を示すバナーが表示されています。

Emails

API が非推奨になると、Shopify は影響を受けるプライベートアプリの開発者の緊急用メールアドレスにメールを送ります。このメールには、お客様のアプリに影響を与える変更点の詳細な説明と、移行に役立つリソースへのリンクが含まれています。

非推奨 API コールのエンドポイント

アプリ開発者は、アプリの認証情報を使用して、最近の非推奨リクエストの詳細なリストを取得できます。このリストでは、最近の非推奨リクエストの詳細な内訳と、そのリクエストに直接影響する変更点を知ることができます。

詳細は、このエンドポイントの完全なドキュメントを参照してください。

終わりに

ここまでで、今回の記事は終了です。お疲れさまでした。

目次
目次
  1. 目次
  2. Shopify API のアクセススコープについて
  3. 認証されたアクセススコープについて
  4. 認証されていないアクセススコープについて
  5. Shopify API authentication | Shopify の API 認証について
  6. 認証の種類| Types of authentication
  7. ShopifyAPI へのバックエンドリクエストの認証| Authenticating your backend requests to Shopify APIs
  8. 組み込みアプリでのマーチャントの認証| Authenticating merchants on embedded apps
  9. 認証されていない API | Unauthenticated APIs
  10. API アクセスモード| API access modes
  11. Tip
  12. オンラインアクセス
  13. オフラインアクセス
  14. ツール| Tools
  15. GraphQL   AdminAPI を使用して一括操作を実行する
  16. 一括クエリの導入[](https://shopify.dev/api/usage/bulk-operations/queries#bulk-query-overview)
  17. Step 1. クエリを送信する[](https://shopify.dev/api/usage/bulk-operations/queries#step-1-submit-a-query)
  18. Step 2. オペレーションのステータスをポーリングする[](https://shopify.dev/api/usage/bulk-operations/queries#step-2-poll-your-operation-s-status)
  19. Step 3. データを取得する[](https://shopify.dev/api/usage/bulk-operations/queries#step-3-retrieve-your-data)
  20. 一括クエリワークフロー[](https://shopify.dev/api/usage/bulk-operations/queries#bulk-query-overview)
  21. 潜在的な一括クエリを特定する[](https://shopify.dev/api/usage/bulk-operations/queries#identify-a-potential-bulk-query)
  22. 一括操作を書く[](https://shopify.dev/api/usage/bulk-operations/queries#write-a-bulk-operation)
  23. 実行中の一括操作をポーリングする[](https://shopify.dev/api/usage/bulk-operations/queries#poll-a-running-bulk-operation)
  24. 操作の進行状況を確認する[](https://shopify.dev/api/usage/bulk-operations/queries#check-an-operations-progress)
  25. 結果データをダウンロードする[](#download-result-data)
  26. JSONL データ形式[](https://shopify.dev/api/usage/bulk-operations/queries#the-jsonl-data-format)
  27. JSONL ファイルを逆に読む[](https://shopify.dev/api/usage/bulk-operations/queries#read-the-jsonl-file-in-reverse)
  28. 例[](https://shopify.dev/api/usage/bulk-operations/queries#example)
  29. Efficient: reads the file a single line at a time
  30. Inefficient: reads the entire file into memory
  31. 実行の失敗[](https://shopify.dev/api/usage/bulk-operations/queries#operation-failures)
  32. キャンセルされた操作[](https://shopify.dev/api/usage/bulk-operations/queries#canceled-operations)
  33. 操作のキャンセル[](https://shopify.dev/api/usage/bulk-operations/queries#canceling-an-operation)
  34. レート制限[](https://shopify.dev/api/usage/bulk-operations/queries#rate-limits)
  35. 一括操作が AdminAPI のレート制限内にどのように収まるか[](https://shopify.dev/api/usage/bulk-operations/queries#how-bulk-operations-fit-within-the-admin-api-rate-limits)
  36. 動作制限[](https://shopify.dev/api/usage/bulk-operations/queries#operation-restrictions)
  37. 次のステップ[](https://shopify.dev/api/usage/bulk-operations/queries#next-steps)
  38. GraphQL AdminAPI を使用したデータの一括インポート
  39. 要件[](https://shopify.dev/api/usage/bulk-operations/imports#requirements)
  40. 制限事項[](https://shopify.dev/api/usage/bulk-operations/imports#limitations)
  41. データの一括インポートの仕組み[](https://shopify.dev/api/usage/bulk-operations/imports#how-bulk-importing-data-works)
  42. JSONL ファイルを作成し、GraphQL 変数を含めます[](https://shopify.dev/api/usage/bulk-operations/imports#create-a-jsonl-file-and-include-graphql-variables)
  43. ファイルを Shopify にアップロードします[](https://shopify.dev/api/usage/bulk-operations/imports#upload-the-file-to-shopify)
  44. アップロードされた URL とパラメータを生成します[](https://shopify.dev/api/usage/bulk-operations/imports#generate-the-uploaded-url-and-parameters)
  45. 例[](#example)
  46. JSON ファイルをアップロードする[](https://shopify.dev/api/usage/bulk-operations/imports#upload-the-jsonl-file)
  47. バルクミューテーション操作を作成する[](https://shopify.dev/api/usage/bulk-operations/imports#create-a-bulk-mutation-operation)
  48. 例[](#example)
  49. 操作のステータスをポーリングします[](#poll-the-status-of-the-operation)
  50. 結果を取得する[](#retrieve-the-results)
  51. 操作の成功[](#operation-success)
  52. 操作の失敗[](#operation-failures)
  53. 操作をキャンセルする[](#cancel-an-operation)
  54. 次のステップ[](#next-steps)
  55. idempotent リクエスト
  56. idempotency キー
  57. idempotent リクエストの仕組み
  58. idempotency キーを受け付けるリソース
  59. GraphQL Admin API
  60. GraphQL Storefront API
  61. REST Admin API
  62. Shopify APIs について
  63. Shopify の API を使用するための要件
  64. スコープとパーミッション
  65. 利用可能な API
  66. Admin API
  67. Storefront API
  68. Partner API
  69. Liquid
  70. Ajax API
  71. 非推奨 API
  72. REST Admin API にページネーションされたリクエストを作成
  73. 使い方 | How it works
  74. リンクヘッダー | Link headers
  75. パラメータ | Parameters
  76. サポートされているエンドポイント | Supported endpoints
  77. 2021 年 1 月リリース
  78. 2019 年 10 月リリース
  79. 2019 年 7 月リリース
  80. Saved searches
  81. ページネーションされたリクエストを作成し、ページを繰り返し処理する
  82. 特定のページの結果の数を変更する
  83. GraphQL による結果のページング
  84. コネクションの概要
  85. pageInfo フィールド
  86. カーソルフィールド
  87. カーソルベースのページネーション
  88. Shopify API レート制限
  89. API によるレート制限の比較
  90. リーキーバケットアルゴリズム
  91. レート制限方法
  92. GraphQL Admin API のレート制限
  93. REST Admin API のレート制限
  94. ストアフロント API のレート制限
  95. リソースベースのレート制限
  96. レート制限エラーの回避
  97. Shopify API レスポンスステータスとエラーコード
  98. ShopifyAPI 検索構文
  99. 検索クエリ文法の概要
  100. クエリ
  101. 連結語
  102. 条項
  103. 修飾子
  104. コンパレータ
  105. 検索クエリの構文
  106. 用語検索
  107. フィールド検索
  108. 範囲検索
  109. Not クエリ
  110. boolean 演算子
  111. グループ化
  112. フレーズクエリ
  113. プレフィックスクエリ
  114. 特殊文字
  115. Exists クエリ
  116. Shopify APi のバージョン管理 | Shopify API versioning
  117. バージョン管理された API とバージョン管理されていない API | Versioned vs. unversioned APIs
  118. リリーススケジュール | Release schedule
  119. API バージョンの呼び出し | Calling an API version
  120. リリース候補 | Release candidates
  121. 不安定な API のバージョン | Unstable API versions
  122. 非推奨プラクティス | Deprecaution practices
  123. 非推奨のリソースを使用するアプリ
  124. GraphQL API の非推奨プラクティス
  125. REST API の非推奨プラクティス
  126. Webhooks
  127. 技術的なアップデートの取得 | Getting technical updates
  128. いつ Shopify から連絡がありますか? | When will Shopify contact you?
  129. 開発者の連絡先は誰にすればいいですか? | Who should be your developer contact?
  130. 開発者連絡先の更新 | Update your developer contact details
  131. API の連絡先メールアドレスの更新
  132. プライベートアプリの連絡先の更新
  133. パートナー組織の連絡先の更新
  134. 関連リンク | Related links
  135. API ヘルスレポート | API health report
  136. アプリのヘルスレポートを見る | View an app's health report
  137. API ヘルスステータス | API health statues
  138. アップデートアプリのステータス確認
  139. Webhook の非推奨事項の修正 | Fixing webhook deprecations
  140. プライベートアプリのバージョン管理 | Private app versioning
  141. 自分のプライベートアプリが影響を受けているかどうかを知るにはどうすればいいですか?
  142. バナー
  143. Emails
  144. 非推奨 API コールのエンドポイント
  145. 終わりに

recommendおすすめ記事