Shopify+GatsbyJSでのECサイト開発、サブスクリプション実装について調べた



# 背景
- サブスクリプションECをつくってみたいと思い、Shopifyを使ってみたかった
- とはいえモダンな開発環境でやれないかと調べてみることにした
- 近頃ShopifyでSubscription APIがリリースされるということであった

これらに関して関連するトピックについて調べてみたので簡単にまとめてみました。
なお私の知識レベルについていうと、Shopifyで開発・運用した経験があるわけではなく、お試しでショップをつくってやってみたところです。

#Gatsbyでの開発

## Gatsbyとは

GatsbyはReactベースの静的サイトジェネレーター。
ReactのSPAを静的に生成し、よしなにデプロイするようなモダンな開発環境を提供してくれます。

- GraphQLで各種APIからデータをロードする。これを用いたHeadless CMSとの連携が豊富にある（WP, Contentful, Shopify...etc）。
- NetlifyやFirebaseにホスティングし、自動デプロイできるDevOps
- 静的サイトなので爆速（ただ最近はPageSpeed Insightsのスコアが芳しくない）
- 画像最適化プラグインGatsby Imageが便利。製品画像含め画像をwebpで返してくれるなど。


### やろうとした構成
フロントエンドを自前で構築し、CMSなどに提供されるコンテンツを読み込んで使用する構成はヘッドレスとよばれ、サイトの構築方式を開発者が柔軟に選択できる点が魅力です。
ということで、APIにアクセスできればフロントエンドはなんでもよく、Nuxt/Vue、Next.js/Reactなどのフレームワークも代替選択肢となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641888/a947482d-ef1b-7f30-8e45-b610a2f6e8b6.png)

この構成では、カートの「注文に進む」以前のページはすべて自前で作成し、それ以降のセンシティブな部分はShopifyの画面を使うことになります。

Gatsbyで生成されるのはあくまで静的サイトなので、在庫数が更新されたら再デプロイし、在庫切れなどの情報を更新する仕組みが必要そうです。
デプロイ時間はコンテンツ量などに影響されるので、商品数や在庫更新のシビアリティは考慮事項でしょう。
ちなみに、使用経験があるのはNetlifyでのデプロイで、これには5,6分かかる。最近出た[Gatsby Cloud](https://www.gatsbyjs.com/cloud/)を使用すればより高速でデプロイすることができるようです。

### ヘッドレスコマースのPros/Cons

古き良きLiquidテーマで開発するか、ヘッドレスコマースでいくか。
現時点での考慮事項は以下ではないでしょうか。

#### Pros
実装方法を任意に選択できるため、

- 開発者が好きなDevOpsを実現できる
- フロントエンドのベストプラクティスを導入可能で、高速化やよりよいUXを実現できる
- フロントエンドとバックエンドをきれいに分離した構成なので、自由に機能を組み込んでいくことが可能
- ほとんどLiquidのキャッチアップが不要

#### Cons / クリアすべき課題

- SEOや多言語対応周り含めサイトが含むコードは自前で実装しなければならない
- デプロイタイミングと在庫状況のラグ問題を許容できるか
- テーマへのLiquid埋め込みに依存するShopifyアプリが使用できない場合がある

特に3点目は漏れるとクリティカルなので、必要な機能をどうやって実現するかを予め点検する必要があります。
私の検討ケースではサブスクリプションが実現できませんでした（記事後半に記す）。

とはいえ、ECサイトとブランディング/メディアを担うWordPressサイトといった構成が国内向けブランドでも非常によくありますが、課題がクリアされればヘッドレスコマースは非常に魅力的な選択肢に思えます。


## Storefront API

Shopifyとデータをやり取りするためのStorefront APIがあります。

- [Storefront API reference](https://shopify.dev/docs/storefront-api)
- [Building an E-commerce site with Shopify | Gatsby](https://www.gatsbyjs.com/docs/building-an-ecommerce-site-with-shopify/)

Storefront APIを使用するには、Shopify上でプライベートアプリを作成し、[トークンを発行](https://shopify.dev/docs/storefront-api/getting-started)する作業が必要です。
そして、Gatsbyで扱う場合はGatsby Pluginである[gatsby-source-shopify](https://www.gatsbyjs.com/plugins/gatsby-source-shopify/)を用いると容易に導入可能です。

GraphQLでのクエリはGraphQL用のIDEであるGraphiQL（Gatsbyに同梱）で探索することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641888/422af253-0401-a799-83fc-5cb279278899.png)

例えば商品詳細ページのクエリはこんな様子。

```javascript:product.js
export const query = graphql`
  query($id: String!) {
    shopifyProduct(handle: { eq: $id }) {
      handle
      id
      title
      handle
      productType
      descriptionHtml
      shopifyId
      options {
        id
        name
        values
      }
      variants {
        id
        title
        price
        availableForSale
        shopifyId
        selectedOptions {
          name
          value
        }
      }
      images {
        originalSrc
        id
        localFile {
          childImageSharp {
            fluid(maxWidth: 910) {
              ...GatsbyImageSharpFluid_withWebp_noBase64
            }
          }
        }
      }
    }
  }
`
```

## スターターキット
ECサイトの最低要件は似たようなものなので、すでに用意されているGatsbyテーマを使用すると楽です。
公開済みストアのURLとプライベートアプリのトークンをenvに記載すればすぐに実ストアのデータを用いたローカル環境を立ち上げることができます。
ローカルでもReactのContextでカート状態をもち、買い物かごページにある「購入に進む」を押すとそこからはShopifyの世界です。

- [gatsby-shopify-starter](https://www.gatsbyjs.com/starters/AlexanderProd/gatsby-shopify-starter)

このスターターキットを用いた導入手順は以下の記事で解説されています。
 [ShopifyとGatsbyJSでヘッドレスコマースサイトを作る方法](https://www.non-standardworld.co.jp/23224/)



# サブスクリプションについて

### Shopifyアプリ

まずよくある方法としては、サードパーティのShopifyアプリをインストールし、テーマにUIを組み込むことになります。
よく言及されるところでは、以下が挙げられます。

- [Bold Subscription](https://apps.shopify.com/bold-subscriptions?locale=ja&surface_detail=subscription&surface_inter_position=1&surface_intra_position=5&surface_type=search)
- [PayWhirl Recurring Payments](https://apps.shopify.com/paywhirl?locale=ja&surface_detail=subscription&surface_inter_position=1&surface_intra_position=6&surface_type=search)
- [Subscription by Recharge](https://apps.shopify.com/subscription-payments/reviews?page=1&rating=3&sort_by=recent)

サービスによりプラン設定の柔軟性などが少しずつ違うようですが、全体的な留意点は以下になるでしょう。

- いずれもUIの組み込みを伴うので、使用するテーマにLiquidをIncludeする作業が必要。（BoldやPaywhirlではボタン一発でこれをやってくれる機能がある！）
- 元から多言語対応がされているわけでないため、自前で日本語を入れていく必要がある。

PaywhirlとBoldをいれて注文までやってみましたが、なかなか簡単に実現することができました。
Paywhirlが固定料金なしでいれられるので、おためしでやってみるにはこの記事を参照。
[【2020年版】PayWhirl で Shopify に定期購買機能を追加！ アップデート・日本語にも対応！](https://shopify.huckleberry-inc.com/sales/sales-discount/subscription-app/)


### APIで利用する方法
BoldやRechageはもともと単なるShopifyアプリではなく、WooCommerceなど他のプラットフォームに対応した決済SaaSであり、APIによるアクセスも提供しています。
（Paywhirlはなさそうでした）

- [Create custom headless commerce experiences anywhere, any way. | Bold](https://boldcommerce.com/headless)
- [Headless Subscription Builds - ReCharge Payments](https://rechargepayments.com/resources/headless-subscription-builds/)

よって、Bold等のAPIを使った自前実装であればヘッドレスでもサブスクリプションは実現可能のようです。
もっともShopifyと統合されたBoldアプリとAPIの繋ぎこみについてはよく調べてません…。

### 組み込む方法

以上をふまえると、サブスクリプションを必須とした導入方法は以下に成約されます。

- Liquid製テーマに、Liquid製アプリで組み込む
- ヘッドレスで構築したサイトでサブスクリプションベンダーのAPIにアクセスし、フロントエンドを独自実装する

### ShopifyのSubscription APIとは

2020年10月に、Shopifyから[ShopifyサブスクリプションAPIについて：Shopifyチェックアウトと統合できるアプリの構築](https://www.shopify.jp/blog/partner-subscription-api)という記事が公開され、一瞬テンションがあがったのですが、これをもってアプリが不要になったということではありません。
Shopifyは完全にネイティブなサブスクリプションの方法を提供するのではなく、ShiopifyのCheckoutという決済機構にサブスクリプションを組み込み、それをAPIでアプリベンダーに開放したという話みたいです。よって、注文データの作成やUIはShopifyアプリが担い、注文の保持や決済はShopifyが担うという分担です。（間違ってたらすみません）
なお、決済方法はShopify Paymentに限定されるよう。

※[上記記事の英語版](https://www.shopify.com/partners/blog/shopify-subscription-apis)のコメント欄が参考になりました。

以前の状態がどんな感じだったかわかりませんが、BoldやPaywhirlはすでにこれに対応し、Shopifyのネイティブなサブスクリプションと統合されているようです。

# 個人的な所感

今回私がめざした検討ケースでは、1人でさっとできる範囲でヘッドレスコマースを実現したかったのですが、Bold等のAPIをGatsbyのスターターに組み込む作業は重そうだなと少し気後れしているところです。
しかしながら、よくあるECサイト+ブランドサイトのような構成を実現する場合はヘッドレスコマースが非常に魅力的で、やってみたいところです。

このあたりのトピックは引き続き試していきたいので、他の方のベストプラクティスをお待ちしてます。