先日、自前でAPIを用意してShopifyのブログ記事一覧を取得しましたが、前回、商品一覧を取得する際にGraphQLの使いかたを学んだので、GraphQLで書き換えてみます。
blog.kimizuka.org
blog.kimizuka.org
手順
プライベートアプリを用意して、ストアフロントAPIのアクセストークンを取得する
毎回のことですが、ストアフロントAPIのアクセストークンが必要になるので取得します。
- プライベートアプリを用意する
- ストアフロントAPIを有効にする
- 商品、バリエーション、コレクションを読み込むの権限を付与する
- ストアフロントのアクセストークンを控える
と、こちらの手順通り進めましょう。
コードを書く
src/pages/graph-ql-blog-list-page.tsx
import gql from 'graphql-tag'; import { ApolloClient } from 'apollo-client'; import { createHttpLink } from 'apollo-link-http'; import { setContext } from 'apollo-link-context'; import { InMemoryCache } from 'apollo-cache-inmemory'; type Data = { articles: { edges: { cursor: string; node: { blog: { title: string; }; title: string; }; }[]; }; }; export default function GraphQlBlogListPage({ data }: { data: Data; }) { return ( <ul> { data.articles.edges.map(({ node }, i) => <li key={ i }>{ node.title } - { node.blog.title }</li> ) } </ul> ); } export async function getStaticProps() { const httpLink = createHttpLink({ uri: `https://${ process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN }/api/graphql` }); const middlewareLink = setContext(() => ({ headers: { 'X-Shopify-Storefront-Access-Token': process.env.NEXT_PUBLIC_SHOPIFY_STORE_FRONT_ACCESS_TOKEN || '' } })); const client = new ApolloClient({ link: middlewareLink.concat(httpLink), cache: new InMemoryCache(), }); const { data } = await client.query({ query: gql`{ articles(first: 250 reverse: true) { edges { node { cursor blog { title id } title content excerptHtml } } } }` }); return { props: { data } }; }
前回同様、importはしていませんが、graphqlも必要になるので、
yarn add graphql graphql-tag apollo-client apollo-link-http apollo-link-context apollo-cache-inmemory
と、必要なモジュールをaddしておく必要があります。
クエリの書き方はこちらにまとまっていました。
ブログを跨いで記事を取ってくるので若干の戸惑いがありました。
引数でblog_idを渡して絞り込むことができれば便利だと思うのですが、それはできないみたいなので、特定のブログ記事のみを表示したい場合は、値の取得後にblogのid(今回は取得せず)か、titleでフィルターを掛ける必要があります。
また、自前APIで取得したときは251件目以降をどうやって取得するか悩みましたが、GraphQLのArticleは引数でafterを渡せるので、返ってきたcursorをafterに渡すことで、それ以降の記事を取得することができます。便利です。
ページングに関してはこちらに詳しくまとまっています。