このエントリはMagento Advent Calendar 2019の18日目です。

今回はMagento2.3系から装備された「GraphQL API」を使って、別サイトにMagento上にあるデータを表示させてみましょう。

必要になる知識

GraphQLを使った実装をするためには、

  • Magento APIの使い方
  • GraphQL APIの使い方
  • JavaScript(必要であれば)
  • Cross-Origin Resource Sharing(CORS)に関する知識

が必要になります。

Magento APIは、以前取り上げたREST APIの記事で認証方法などを紹介しています。
GraphQL APIは以前の記事DevDocsを参考にしてください。

ブラウザ上からGraphQL APIを使うときはCORSに注意

サーバーサイドでGraphQL APIを呼び出してデータ取得をする場合には意識しなくても構いませんが、JavaScriptを用いてクライアントのブラウザ上からGraphQL APIを利用する場合は、CORSについて知っておく必要があります。
MDNの記事に詳しく書かれていますが、要はよそのドメインに対してJavaScript経由での利用を制限・許可するものです。
何もしていなければApacheやNginxは同一ドメイン間でしか利用できない設定になっています。

別サイトから利用したい場合の設定

別サイトからJavaScript経由でMagento上のデータを利用したい場合は、ApacheやNginxに以下のような設定が必要です。
(あくまで例なので、要件に合わせて変えてください)

Apache

Header set Access-Control-Allow-Origin "許可するドメイン名"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT"
Header set Access-Control-Allow-Headers "Origin, Authorization, Accept"

Nginx

add_header Access-Control-Allow-Origin 許可するドメイン名;
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS PUT";
add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
add_header Access-Control-Allow-Credentials true;

環境によってはサーバー設定が変更できない場合もあると思います。
その場合は、Yireo CorsHack のようなエクステンションを入れることで解決できるでしょう。

JavaScriptからGraphQL APIで商品データを呼び出してみる

では、実際にGraphQL APIを使ってJavaScriptからデータを呼び出してみましょう。
JavaScriptの書き方は色々あると思いますが、今回はベタにjQueryで書くことにします。

下記のようなコードを書いて実行してみましょう。

$.ajax({url: "http://Magentoのドメイン名/graphql",
                  contentType: 'application/json',
                  type:'POST',
                  data: JSON.stringify({ query: `{ 
    products (
        filter: {
          name: { like: "%キーワード%"}
        }
        pageSize: 18
    ) {
        total_count
        items {
            id
            name
            url_path
            thumbnail {
                url
            }
            price {
                regularPrice {
                    amount {
                        value
                        currency
                    }
                }
            }
        }
    }
}`
                  }),
                  success: function(result) {
                     console.log(JSON.stringify(result))
                  }
               });

正しく実行できれば、以下のように一致する商品のデータがJSON形式で得られます。

{
  "data": {
    "products": {
      "total_count": 3,
      "items": [
        {
          "id": 6,
          "name": "テスト商品",
          "url_path": null,
          "thumbnail": {
            "url": "商品画像URL"
          },
          "price": {
            "regularPrice": {
              "amount": {
                "value": 100,
                "currency": "JPY"
              }
            }
          }
        }
      ]
    }
  }
}

あとはこのJSONデータを使って、描画を行えばOKです。

Insomniaなどのツールを使えば、スキーマ定義を確認しながらクエリを書けます。何もツールを使わずにGraphQLのクエリを書くのは少し大変かもしれません。
ある程度形になったクエリをJavaScriptファイルに移植し、調整すれば安全にGraphQLを使ったデータ連携ができるでしょう。

Magento2.3.2以降ではGraphQL APIの実行結果をVarnishにキャッシュする定義が付属しています。REST APIでは実行結果をキャッシュすることができずパフォーマンスに難がありましたが、GraphQL APIであればより速く結果を得られます。

GraphQL APIは他にも様々なスキーマが定義されていて、ログイン中の顧客が自分の注文履歴やカート情報を参照することもできます。
Magentoのフロントエンドに不満のある方は、GraphQL APIを使用すれば自由にフロントエンドを構築できます。

次回はGraphQL APIを使って「データ更新」を行うための「Mutation」について解説します。