当サイトは、アフィリエイト広告を利用しています
GatsbyにおけるGraphQLの役割や使い方についてまとめてみる
Gatsbyでは各データソースからデータを取得する際はGraphQLを使う。
GraphQLを使うことで異なるサーバーやmicroCMS,ローカルから効率的にデータを取得できる。
このGraphQLには
があり、できることや使い方やに違いあるので整理していく
GraphQLの前にGatsbyデータシステムの中心となる「ノード」について
簡単にまとめる。
GatsbyではGatsbyに追加されるすべてのデータはノードを使用してモデル化される。
簡単に言い換えてみると
などのデータソースは全てGatsby上ではノードとして扱われる。
ちなみにノードの構造は下記のような感じになってる
interface Node {id: string;children?: Array<string>;parent?: string;fields: object;internal: {contentDigest: string;mediaType?: string;type: string;owner: string;fieldOwners: object;content?: string;description?: string;};[key: string]: unknown; // ...other fields specific to this type of node}
GraphQLはこのノードに対してクエリを投げてデータを取得することができる。
つまり、異なるデータソースでもGatsby上では全てノードとなっているので
GraphQLを使って一元的に扱うことができる。
※ちょっと文章だけだと難しいので後でサンプルを載せます
Gatsbyには多くのプラグインがあり、サイトの用途に合わせて必要なプラグインを組み合わせて
使用していく必要がある。
プラグインには用途によって種類がかなりあるのでここではGraphQLでデータを取得する際に
使用するプラグインの役割をまとめる。
データ取得系のプラグインは例えば下記などがある。
これらはインストールすることでそれぞれのリソースにgraphQLでアクセスできるようになる
※プラグインはリソースをノードに変換してGatsbyからgraphQLでアクセスできるようにしている
サンプルとしてgatsby-source-contentfulのイントール前と後を
GraphiQL(GraphQLのIDE)で確認してみるとcontentfulのデータが追加されていることがわかる。
contentfulの項目がない
allContentfulBlogPostというcontenfulのデータが増えている。
このように適宜、必要なプラグインを追加することで下記のようなことができるようになる。
※実際に行う場合は、プラグインのインストールに加えて、gatsby-config.jsで設定を書く必要がある。
Gatsbyでcontentfulのデータを扱う方法については下記に記事でまとめています。
Gatsbyで使用するGraphQLは大きく分ける
の2種類がある。
pageQueryはpageとなるコンポーネントでのみ使用できるGraphQL。
具体的には「pages/ディレクトリ」と「templateディレクトリ」配下にあるファイル内で
使用することができる。
仮の当ブログの記事のタイトルを一覧で表示する下記のようなページを
pageQueryを使って作成してみる
タイトルを羅列しただけのページ!!
上記ページに表示させるタイトルをcontentfulから取得するGraphQLを作成する
GraphiQLでは項目を選んでいくだけでGraphQLを作成できる
作成したGraphQLを使ってindex.jsxを作成する
GraphiQLの「Code Exporter」を使えばテンプレートを自動生成してくれる
自動生成したソースを書き換えてタイトル一覧を表示するようにする
import * as React from "react"import { Link, graphql } from "gatsby"const BlogIndex = ({ data }) => {const nodeList = data.allContentfulBlogPost.edgesreturn (// 取得したタイトルを一覧で表示する<div>{nodeList.map(({ node }) => {return (<div><Link to={node.slug}>{node.title}</Link></div>)})}</div>)}export default BlogIndex// 記事のタイトルとslugを取得export const pageQuery = graphql`query {allContentfulBlogPost {edges {node {titleslug}}}}`
pageQueryはbuild時に静的ページ生成を行う際、
template/ディレクトリ配下のファイルでも使用できる。
pages/ディレクトリ配下で使うpageQueryとの違いは
こと。
静的ページを作成する時のサンプルを作ってみる
const path = require(`path`)exports.createPages = async ({ graphql, actions }) => {const { createPage } = actions// contentful記事のkeyを取得const contentfulAirticleResult = await graphql(`query airticleQuery {allContentfulBlogPost {edges {node {slug}}}}`)const contentfulAirticle =contentfulAirticleResult.data.allContentfulBlogPost.edges//記事数分ループして記事ページを作成するcontentfulAirticle.forEach(({ node }) => {createPage({path: `${node.slug}/`, //記事ページのurlcomponent: path.resolve(`./src/templates/contentfulPost.jsx`), //記事ページ作成のtemplateコンポーネント//templateコンポーネントに渡す引数context: {slug: node.slug,},})})}
import React from "react"import { graphql } from "gatsby"import MDXConvert from "../components/mdxConvert"const ContentfulPost = ({ pageContext,data }) => {const post = data.allContentfulBlogPost.edges[0].nodeconst { body } = post// MDX形式の記事データをMDXConvertでhtmlに変換するreturn <MDXConvert>{body.childMdx.body}</MDXConvert>}export default ContentfulPost// gatsby-node.jsのcreatePageから渡されたslugを元にGraphQLで記事を取得するexport const query = graphql`query Query($slug: String!) {allContentfulBlogPost(filter: { slug: { eq: $slug } }) {edges {node {body {childMdx {body}}}}}}`
※MDX形式でcontentful記事を表示する場合のソースをサンプルにしています
pageQueryに対してstaticQueryはあらゆるコンポーネントで使うことができる。
pagesディレクトリ配下やtemplateディレクトリ配下以外のコンポーネントでは
staticQueryを使ってデータを取得する。
pageQueryで作成した記事タイトル一覧ページの上にタグ一覧を
タグ一覧用コンポーネントを作って表示してみる
pageQueryを作成した時と同様にGraphiQLでGraphQLを作成する
GraphiQLで作成したstaticQueryを使って作成する
import React from "react"import { useStaticQuery, graphql } from "gatsby"const Alltags = () => {//staticQueryconst data = useStaticQuery(graphql`{allContentfulTags {edges {node {title}}}}`)const nodeList = data.allContentfulTags.edgesreturn (// 取得したタグタイトルを一覧で表示する<div>{nodeList.map(({ node }) => {return (<div><button>{node.title}</button></div>)})}</div>)}export default Alltags
タグ一覧表用コンポーネントを追加する
import * as React from "react"import { Link, graphql } from "gatsby"import Alltags from "../components/allTags"const BlogIndex = ({ data }) => {const nodeList = data.allContentfulBlogPost.edgesreturn (// 取得したタイトルを一覧で表示する<div><Alltags />{nodeList.map(({ node }) => {return (<div><Link to={node.slug}>{node.title}</Link></div>)})}</div>)}export default BlogIndex// 記事のタイトルとslugを取得export const pageQuery = graphql`query {allContentfulBlogPost {edges {node {titleslug}}}}`
Gatsbyを起動して画面を表示してみる
タグ一覧が表示されている
GatsbyにおけるGraphQLの使い方とGraphQLの種類(pageQueryとstaticQuery)について
忘れないようにまとめてみた。
staticQueryはどこでも使えるのはいいが、引数が渡せないのでデータ取得を動的に行うことが
できないのがちょっと残念。
Gatsbyを使ってサイト開発するにに読んだ本です。
GraphQLの基本的な使い方についても参考にしました。