Shopify アプリを AWS に SPA + Serverless 構成でデプロイする – React + Amplify / Node.js + Serverless Framework –

前回の「[Shopify でテーマとアプリを開発する – ThemeKit / Shopify App CLI –](https://www.nri-digital.jp/tech/20200525-2042/)」では、Shopify が提供する公式ツールを使った開発方法を解説しました。Shopify App CLI はとても便利なツールなのですが、2020年5月時点では本番環境は heroku へのデプロイのみ提供しています。AWS / GCP / Azure などのクラウドで稼動させる場合は別途 CICD パイプラインを構築する必要があります。また Shopify App CLI で生成されるアプリは koa / Node.js をベースとしており Web サーバーを必要とします。本記事では AWS に SPA + Serverless 構成でデプロイする方法を解説します。

# アーキテクチャ構成
[Shopify Dev Template](https://github.com/t-kurasawa/shopify_dev_template) のサンプルコードを元に解説します。AWS とサーバーレスの説明については割愛します。

- フロントエンド（react-amplified）
 - React を Amplify Hosting で S3 + Cloudfront へデプロイします。Shopify アプリは HTTPS 必須です。

- バックエンド（api-serverless）
 - Node.js / aws-serverless-express を Serverless Framework を使い API Gateway – Lambda – DynamoDB をデプロイします。こちらも HTTPS にします。
![アーキテクチャ事例_最小.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127260/b5759dcb-5a39-ca73-94df-2e3d2e08a31e.png)

# Shopify でアプリ認証し、アクセストークンを元に Shopify API を呼び出す
まずはアプリを作る上で必要になるアプリ認証について解説します。公式が解説している [Authenticate with OAuth](https://shopify.dev/tutorials/authenticate-with-oauth) のフローを熟読してください。[Authorization Code Grant](https://tools.ietf.org/html/rfc6749#section-4.1) のフローに準拠しています。

- 用語の解説
 - MERCHANT：アプリを入れるショップです
 - APP：拡張機能を開発するアプリです
 - SHOPIFY：アプリが通信する Shopify の API です

![oauth-code-grant-flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127260/018fba4f-7d7d-d3a8-e8d2-9324a340a240.png)

## Step 1: Get client credentials
shopify partners アカウントで「アプリ管理」から「アプリを作成する」を押します。次に、公開アプリ・カスタムアプリを選択します。この２つは１つのショップのための拡張開発を行うか、汎用的な拡張機能をアプリとして販売するかの差があります。
<img width="535" alt="アプリ作成.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127260/cbc9c78e-bb72-6597-f2d2-5b3c31f149ec.jpeg">
次にアプリURLとホワイトリストに登録されたリダイレクトURLを登録します。ここは Shopify App CLI を利用すると自動で設定してくれるのであまり意識する必要が無いのですが、使わない場合は設定が必要になります。

- アプリURL（/auth）
 - ショップがアプリをインストールするためのリンク。 Shopify の認証を行います。
- ホワイトリストに登録されたリダイレクトURL（/callback）
 - Shopify の認証が行われた後に、利用する API の権限等を確認し、権限を付与した後にリダイレクトされる URL

権限や API バージョンなど必要な情報を設定したら、アプリで利用する API キーとシークレットキーを取得出来ます。シークレットキーは公開してはいけません。
<img width="701" alt="リダイレクト.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127260/4c78886d-5401-c736-781e-c59e8c66622f.jpeg">

## Step 2: Ask for permission
ショップがアプリをインストールするためのリンク（/auth）を押した後に、権限の確認と付与を行う Shopify の画面が表示されます。アプリをインストールすると指定の URL へリダイレクト（ /callback ）します。

上記の実装は react-amplified/src/Auth.js を参照して下さい。やっていることは以下の Shopify の oauth/authorize へリクエストを送っているだけです。

`https://{shop}.myshopify.com/admin/oauth/authorize?client_id={api_key}&scope={scopes}&redirect_uri={redirect_uri}&state={nonce}&grant_options[]={access_mode}`

![アプリ権限付与.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127260/6ad3a5b6-5f25-daa5-8179-49e13cf7c06b.png)

## Step 3: Confirm installation
リダイレクトされた画面（ /callback ）には URL パラメータとして code, hmac, shop, timestamp が送られてきます。取得した認証コードとアプリ作成時に得た API キーとシークレットキーを Shopify の oauth/access_token へ渡します。

`POST https://{shop}.myshopify.com/admin/oauth/access_token`

- client_id: The API key for the app, as defined in the Partner Dashboard.
- client_secret: The API secret key for the app, as defined in the Partner Dashboard.
- code: The authorization code provided in the redirect.

正しく処理された場合はアクセストークンを取得できます。

`{ “access_token“: “this_is_sample_access_token“, “scope“: “write_orders,read_customers“ }`

上記の実装は react-amplified/src/Callback.js と api-serverless/functions/app.js の /oauth を参照して下さい。シークレットーキーの扱いや hmac の検証はバックエンドで行っています。

## Step 4: Making authenticated requests
アクセストークンを取得したら HTTP の ヘッダーに X-Shopify-Access-Token: {access_token} を付けて REST API 通信を行って下さい。

# Shopify アプリを AWS 上で動かす
Step 1-4 を実施することで Shopify のデータを API 経由で取得する準備が出来ました。それでは AWS 上にアプリを準備しましょう。

- フロントは React で開発し Amplify で S3 + Cloudfront にホスティングします。（[react-amplified/README.md](https://github.com/t-kurasawa/shopify_dev_template/tree/master/app/react-amplified/README.md) 参照）
- バックエンドは Node.js / aws-serverless-express で開発し Serverless Framework で API Gateway – Lambda にデプロイします。（[api-serverless/README.md](https://github.com/t-kurasawa/shopify_dev_template/blob/master/app/api-serverless/README.md) 参照）

実装は react-amplified/src/Top.js と api-serverless/functions/app.js の /products を参照して下さい。React から直接 Shopify API を呼び出しても構いませんが、本サンプルでは今後の拡張性のために間に Lambda を挟んでいます。

Shopify の API を利用できるようになったことで、管理画面内外のいずれでも商品データを扱うことが出来るようになります。API を経由することで機能の一部分だけを切り出して拡張開発をすることが出来ます。本サンプルでは薄く作ることを意識していますが、Shopify アプリの開発ライブラリとして app-bridge や polaris がありますのでぜひご活用下さい。

本記事では実施しませんでしたが Shopify App CLI が生成する koa や Next.js を Lambda@Edge や aws-serverless-express でラッピングしていくことで Serverless 構成を実現出来るだろうと見込んでいます。

![アプリ構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127260/522ed5f3-627f-1bc9-0c64-24d528cfbc3d.png)

# まとめ
本記事では Shopify アプリを AWS で動かす方法を解説しました。次回以降はより実践的な開発を深堀りしていきます。

<本記事に関するお問い合わせ>
NRIデジタル株式会社　担当　吉田・倉澤・萩村 and Developers　marketing-analytics-team@nri-digital.jp

> 本記事は NRI digital TECH BLOG からの転載です。
> [Shopify アプリを AWS に SPA + Serverless 構成でデプロイする – React + Amplify / Node.js + Serverless Framework –](https://www.nri-digital.jp/tech/20200526-2059/)