Skip to content
Pepinby SHIN
Shopify2026-04-247分で読めます
Shopifyアプリ開発アーキテクチャ

3 Shopify App Architecture Pitfalls I Hit Building the Marutto Series

3 Shopify App Architecture Pitfalls I Hit Building the Marutto Series

Shopifyアプリを自分で作ろうとして、「どのフレームワークで組むか」「認証はどう扱うか」「APIはどう叩くか」で手が止まったことはないでしょうか。わたしも2026年1月に独立してから、自宅デスクで「まるっとシリーズ」を作る過程で、何度も同じところで詰まりました。

この記事では、そのうち 設計初期で踏んだ3つのアーキテクチャ選定ミス を、ケーススタディとして共有します。あとから振り返ると公式ドキュメントに答えが書いてあった話ばかりなのですが、初見で正解にたどり着くのは難しい領域でした。これから1本目を作る方にとって、遠回りを数週間は短縮できる内容になっているはずです。

これはわたしが2026年1〜4月に 5本のShopifyアプリ(まるっとシリーズ)を実装する中で踏んだ、アーキテクチャ選定の個人的な学びです。プロジェクトの規模や要件によって最適解は異なりますので、あくまで一次情報として参考にしてください。

これから作る人が最初に抱える不安

Shopifyアプリ開発は、一般的なWebアプリ開発と似て非なるものです。フロントもバックも書いた経験があっても、最初の1本目では次のような疑問にぶつかります。

  • 認証周りは何を使えばいい? OAuthなのかSession Tokenなのか
  • フレームワークは好きなものでいいのか、公式推奨があるのか
  • Admin APIはどう叩くと怒られないのか(Rate Limit)
  • Embedded App と Standalone、どちらで作るのが普通なのか

わたしは1本目の「まるっと予約」を組み始めたとき、このうち上の3つを盛大に外しました。結果、リリース直前にアーキテクチャをごそっと組み替えることになり、1〜2週間まるごと作り直しています。

Shopifyアプリ開発の初期につまずくイメージ

事例: まるっとシリーズで踏んだ設計判断 3つ

ここからが本題です。まるっと予約からまるっとフォルダ管理までの5本を通して、同じ過ちを繰り返さないように積み上げてきた3つの判断を、ビフォーアフターで紹介します。

  1. 2026-03-17

    まるっと予約(リリース済み)

    この1本目で、認証・フレームワーク・API呼び出しの3点を全部外しました。

  2. 2026-04-15

    まるっと法務作成(リリース済み)

    予約で得た反省を踏まえて、公式テンプレに寄せて組み直した1本。

  3. 2026-04-22

    まるっとフォルダ管理 / FileFolders(リリース済み)

    最初からBulk OperationとWebhookを前提に設計できた1本。体感で開発速度が倍になりました。

ミス1: Session Token を自前でキャッシュしようとした

まるっと予約の初期実装で、最初にやらかしたのがこれです。Shopifyアプリでは、埋め込み画面からバックエンドを叩くときに Session Token という短命なJWTを使います。わたしはこれを「サーバー側でRedisに入れてキャッシュすれば通信コストが下がるのでは」と考え、独自キャッシュ層を組みました。

Session Token

Shopify埋め込みアプリで、管理画面とアプリバックエンドの通信を認証するための短命なJWT(JSON Web Token)。App Bridgeが発行・更新を自動で行うため、アプリ開発者が寿命や保管を管理する必要は基本ありません。

結果として何が起きたか。トークンの寿命は 約1分 と短く、自前キャッシュをしても使い回せる時間がほぼない。さらにキャッシュヒット率を上げるためにTTLを延ばすと、期限切れトークンで401連発。セキュリティ的にも宜しくなく、公式の推奨は「毎回App Bridgeから取得し、バックエンドで検証のみする」でした。

公式には Token Exchange という仕組みが用意されていて、Session Tokenをバックエンドに渡すと、必要なAccess Tokenに安全に交換してくれます。これに乗り換えた瞬間、自前キャッシュのコードが100行ほど消えました。

Before: 自前キャッシュ

Session TokenをRedisに保持 → TTL調整で401連発 → キャッシュ無効化ロジックが肥大化 → コードレビューで毎回ここが議論の的に

After: App Bridge + Token Exchange

App Bridgeが毎回最新トークンを発行 → バックエンドはJWT署名検証のみ → キャッシュ層を完全撤去 → 実装コードが約100行減

Session Tokenは「管理するもの」ではなく「検証するもの」。自前でキャッシュ・永続化したくなったら、設計を疑ったほうが良いサインです。

出典:Shopify App Bridge library (Session token / idToken)

ミス2: 好きなフレームワークで組み始めた

2つ目のミスは、フレームワーク選定です。まるっと予約の最初の実装は、慣れていた Rails + React(SPA) で組み始めました。理由は単純に「書き慣れているから」。ところがShopifyエコシステムにおいて、この選択は地雷でした。

何が問題だったか。Shopify CLIの shopify app init で出てくる公式テンプレートは、Remix系(現在はReact Router v7ベース)を前提に組まれています。開発サーバー、ngrokトンネル、Webhookローカル受信、App Bridge初期化、セッション検証、このあたりが 全部プリセットで動く状態 で降ってきます。自前スタックで組むと、これらを自力で再発明することになります。

わたしは2週間ほどRails + Reactで粘ったあと、WebhookのHMAC検証とEmbedded画面のCSP設定でハマり、 公式テンプレートに戻しました 。戻した瞬間、ローカルでストアに接続するまで15分。これを自前で組もうとしていた自分を責めました。

  1. 1

    公式CLIで雛形を作る

    shopify app init を実行し、推奨テンプレートを選ぶ。2026年現在はReact Routerベースのテンプレートが推奨です。

  2. 2

    認証・Webhook・App Bridgeの初期配線を確認する

    テンプレートに同梱されている shopify.server.ts / authenticate.ts 相当の配線を読む。自分で書かない。

  3. 3

    機能コードだけを足す

    データモデル・画面・ロジックを、テンプレートの上に乗せる感覚で追加する。基盤には触らない。

  4. 4

    逸脱したくなったら一度立ち止まる

    「別のフレームワークで書き直したい」と思ったら、9割の確率でその時間は回収できないと覚えておく。

公式テンプレにはShopifyが何年もかけて踏んだ地雷の回避策が詰まっています。 慣れた道具 より 公式のレール を優先したほうが、ソロでは確実に速い。

出典:Shopify CLI: Scaffold an app

公式テンプレに戻す判断のイメージ

ミス3: Admin API を逐次リクエストで叩いた

3つ目は、GraphQL Admin APIの使い方です。まるっと予約では、予約に紐づく商品情報をまとめて取りにいく処理で、商品1件ずつ query { product(id) { ... } } を発行していました。100件の予約に対して100本のクエリ。牧歌的な実装です。

ShopifyのAdmin APIは Calculated query cost(計算型コスト) 制で、標準プランで100ポイント/秒、Plusで1000ポイント/秒。小さいクエリを連発すると、あっさりバケットを使い切ってスロットリング(THROTTLED)が返ってきます。わたしは最初、この仕組みを誤解して「1秒に何リクエストまで」で考えていました。正しくは 「クエリの複雑度の合計ポイント」 です。

救世主が2つありました。1つは Bulk Operation 。数万件規模のデータを非同期ジョブとして一度に取れる仕組みで、ポイントは1回分しか消費しません。もう1つは Webhook で、在庫や注文の変更をプッシュで受け取って自分のDBに同期しておき、読み取りはDBから行う設計です。

Bulk Operation

Shopify Admin GraphQLが提供する、大量データ取得・書き込み用の非同期ジョブAPI。1回のmutationで対象クエリを登録すると、バックグラウンドでJSONL形式のファイルを生成し、完了通知とダウンロードURLを返してくれます。Rate Limitの消費は登録時の1回分のみ。

まるっとフォルダ管理(FileFolders)では最初からこの前提で組めたので、数万件規模のファイル一覧取得でもスロットリングゼロでリリースできました。以下は、わたし個人比の単純比較です。

100
Before: 1画面描画あたりAPIコール数(まるっと予約 初期)
2
After: 1画面描画あたりAPIコール数(Bulk + キャッシュ後)
0
直近1ヶ月のThrottled発生回数(まるっとフォルダ管理)

数字は「わたし個人比」の実測であり、他のアプリやストア規模で同じ結果になる保証はありません。 傾向の目安 として読んでください。

Before: 逐次クエリ

100件のデータに100本のクエリ → レスポンスごとにポイント消費 → バースト時にTHROTTLEDで画面がガタつく

After: Bulk + Webhook同期

一覧取得はBulk Operationで1ジョブ → 変更はWebhookで自DBに反映 → 画面描画はDB参照だけでサクサク

出典:Shopify GraphQL Bulk Operations / 出典:Shopify API rate limits

打ち手: これから作る人の選択フロー

上の3つを踏まえて、1本目を設計する方に向けた判断フローを整理します。わたしが5本目を作る時点で、ようやく自然にたどれるようになった順番です。

  1. 1

    まず公式CLIでスカフォールドを生成する

    shopify app init を実行し、推奨テンプレートを選ぶ。ここで自分の好みのフレームワークを持ち込まない。

  2. 2

    認証はApp Bridge + Token Exchangeに寄せる

    テンプレート同梱のauthenticate.admin / authenticate.public相当のヘルパーをそのまま使う。自前のセッション管理は書かない。

  3. 3

    データ読み取りの設計を先に決める

    「このアプリで扱うデータ量は多いか?」「リアルタイム性は必要か?」を先に答える。大量ならBulk Operation、更新追従ならWebhook。

  4. 4

    課金フローはShopify Billing APIに寄せる

    独自の決済を挟まない。審査で高確率で跳ねます。

  5. 5

    最後にUIとドメインロジックを足す

    基盤が固まってから、自分の勝負所であるUI・機能に時間を投下する。

設計判断のフローのイメージ

結果: まるっと予約 → まるっとフォルダ管理で変わったこと

1本目から5本目までの間に、定量・定性の両面で変化がありました。あくまで わたし個人比 ですが、参考までに並べます。

14
まるっと予約 初期実装のやり直し日数(Rails→Remix系移行)
0
まるっとフォルダ管理でやり直しに使った日数
3
1本目〜5本目でShopify審査に最初の提出で通った本数
Before: 1本目のわたし

好きなフレームワーク / Session Token自前キャッシュ / 逐次クエリ / Webhook後回し

After: 5本目のわたし

公式テンプレ / Token Exchange任せ / Bulk Operation前提 / Webhookで自DBに同期

公式のレールから外れたくなったら、外れる理由をレビュアー(=未来の自分)に説明できるかを一度書き出す。書けないなら、それはただの好みです。

5本目をリリースしたあとの自分

注意点

ここまで「公式に寄せよう」と書いてきましたが、盲目的な適用は推奨しません。いくつか前提を添えておきます。

この記事は B2B向けShopifyアプリを数人以下で作るケース を前提にしています。エンタープライズ要件・Plus専用機能・マルチテナント基盤を組む場合は、公式テンプレをベースにしつつも、別の設計判断が必要になります。

数字はすべて2026年1〜4月、わたし個人の5本実装での実測値です。Shopifyのプラットフォームは更新が速いので、実装前に必ず最新の公式ドキュメントを確認してください。

よくある質問

作れます。公式テンプレートが現在React Router系(旧Remix系)ベースで手厚くサポートされている、というだけです。自力でAuth・Webhook・App Bridgeを組める自信があれば、Next.jsでもAstroでも問題ありません。ただしソロや少人数で速度を出したいなら、レールに乗るほうが圧倒的に早いと思います。

Embedded App(Shopify管理画面内で動くアプリ)を作るなら、Token Exchangeベースのフローが現在の推奨です。Standaloneの古い実装で残っているOAuthフローを新規に真似する必要はありません。公式テンプレートに従えば自然にToken Exchange前提の配線になります。

わたしの基準は「画面描画やバッチ処理で一覧取得が50件を超えそうなら検討、数百件を超えるなら確定」です。小さいうちは普通のqueryで十分ですが、ユーザーのストアが大きくなったときに詰まる前提で、最初から導線だけ引いておくと安全です。

まとめ

まるっとシリーズ5本を通して、アーキテクチャ選定で避けたいミスは次の3つに集約できます。

  1. Session Tokenを自前でキャッシュする(→ App Bridge + Token Exchangeに任せる)
  2. 慣れたフレームワークで公式テンプレを無視する(→ shopify app init から始める)
  3. Admin APIを逐次クエリで叩く(→ Bulk Operation と Webhook に寄せる)

どれも「公式ドキュメントを初見で読んでもピンと来ない」類の判断です。わたし自身、1本目では全部外しました。ただ2本目以降は、この3つさえ抑えておけば土台で詰まることはなくなり、自分の勝負所である 機能とブランドの磨き込み に時間を回せるようになりました。

これから1本目を作る方は、どうかわたしと同じ回り道をせずに、最短で勝負所に入ってください。まるっとシリーズの実装から得た、ささやかだけれど確度の高い学びです。

→ まるっとシリーズを見る

この記事はShopify予約アプリ「まるっと予約」の開発元であるPepinが執筆しています。

Share
SHIN

この記事の執筆者

SHIN

Pepin代表、Webエンジニアとして10年以上の経歴を持ち、
Shopifyアプリ・ストア開発 / webサービス開発 / メディア運営などマルチに活動。

Shopify無料体験を始める

Let's Build Together