Gatsby における GraphQL の機能とよく使う便利な記述を紹介する

# はじめに

この記事は JAMstack Advent Calendar 2018 17日目 の記事です！
2年ほど前に Gatsby に関する記事を初めて Qiita に投稿しました。

> React.js製の静的サイトジェネレーターGatsbyに移行した
https://qiita.com/jaxx2104/items/5f28915355a85d36e38a

当時と比較してバージョンは1未満から2系になり機能も様変わりしました。
特に GraphQL は Gatsby の特徴でもあるので、今回はその説明と、よく使う便利な記述をいくつか挙げて紹介をしたいと思います。

# Gatsby における GraphQL の役割について

役割は主に2つ

- APIの抽象化と再利用性
- パフォーマンス最適化

それぞれについて見ていきましょう

## APIの正規化と再利用性

![27801935-94ff9828-5fd5-11e7-8bbf-66164fc79a11.png](https://qiita-image-store.s3.amazonaws.com/0/29554/ab085ae4-c1d6-3907-f6ed-4e245ba5c1dd.png)

_GatsbyではデータソースをGraphQLで扱います_

Gatsby は一般的な静的サイトジェネレーターと違い利用できるデータソースはマークダウンに限りません。`gatsby-source-xxxxx` という名前のプラグインを使うことで様々なデータを扱うことが可能です。

> GraphQL Plugins | GatsbyJS
https://www.gatsbyjs.org/plugins/?=gatsby-source

例えば Contentful, WordPress, Medium, S3, Firestore などが挙げられます。またデータソースに対して GraphQL が有効になっているので、自由なIFを定義することが可能になっています。外部サービスのAPIを扱う際に、 React の部分に余計な記述を書かなくていいのは、うれしいポイントです。

具体例として Gatsby でできること

- 既存の WordPress の入稿画面はそのまま画面を React 化
- Medium の複数ブログをまとめフィルターすることでメディアサイトを構築
- 個人で作成した S3 や Firestore を使ってサービスを提供

## パフォーマンス最適化

データソース以外に Gatsby はパフォーマンスも面倒をみてくれます。 
例えば `gatsby-image` や `gatsby-remark-images` などのプラグインを使うことで画像表示を最適化します。

説明の前に以下のデモをみてもらうと分かりやすいです。

> Using Gatsby Image 
https://using-gatsby-image.gatsbyjs.org/

機能としては以下です

- 各デバイスのサイズと画面解像度に最適なイメージサイズを読み込みます
- 画像の読み込み中に画像の位置を保持します
- 画像全体が読み込まれている間に表示する画像の小さな画像を読み込みます。
- レイジーは画像をロードして帯域幅を減らし、初期ロード時間を短縮します
- ブラウザーがその形式をサポートしている場合、WebPイメージを使用します。

これらの機能を設定なしで GraphQL から指定することで利用できます。

![Dec-17-2018 00-21-48.gif](https://qiita-image-store.s3.amazonaws.com/0/29554/bdca10af-ca11-fbeb-9e67-2d51aa061d15.gif)

_画像読み込みの最適化_

簡単便利で素晴らしいですよね 💯

# よく使う便利な記述

2つの役割はざっくり説明したので、個人的によく使う便利な記述をいくつか挙げておきます。

## その１: 基本的なブログっぽい設定

- limit: 記事の最大数を3件とする
- filter: 日付が null の記事を除外
- sort: 日付を降順でソート
- format: 日付を `YYYY.MM.DD` にフォーマット
- alias: edges, node を posts, post に変更

```graphql
{
  allMarkdownRemark(
    limit: 3
    filter: { frontmatter: { date: { ne: null } } }
    sort: { fields: [frontmatter___date], order: DESC }
  ) {
    posts: edges {
      post: node {
        frontmatter {
          title
          date(formatString: "YYYY.MM.DD")
        }
      }
    }
  }
}
```

これだけ覚えておけばブログは作成が可能だと思います。

## その2: 画像最適化

- 表示用に画像を最適化した形式で取得
- og:image 用にオリジナル画像も取得

```graphql
{
  allMarkdownRemark(
    limit: 100
  ) {
    posts: edges {
      post: node {
        frontmatter {
            image {
              childImageSharp {
                fluid(maxWidth: 1200) {
                  ...GatsbyImageSharpFluid
                }
                sizes {
                  src
                }
              }
            }
        }
      }
    }
  }
}
```

画像のフォーマットは `GatsbyImageSharpFluid` 以外にもあるので、ドキュメントを読んで指定してください。

## その3: 記事ページと関連記事の取得

- 記事の取得
- 上記の記事以外の関連記事3件を表示

```graphql
{
  post: markdownRemark(frontmatter: { path: { eq: $path } }) {
    frontmatter {
      title
    } 
  }
  related: allMarkdownRemark(
    filter: { frontmatter: { path: { ne: $path } } }
    limit: 3
  ) {
    posts: edges {
      post: node {
        frontmatter {
          title
          image {
            childImageSharp {
              fluid(maxWidth: 300) {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  }
}
```

関連記事以外にもカテゴリ一覧やタグ一覧をサクッと作ることができます。

もっと詳しい解説は公式でしてくれているので参考にしてください。

> GraphQL Reference | GatsbyJS
https://www.gatsbyjs.org/docs/graphql-reference/

# おわりに

いかがでしたでしょうか。 Gatsby の特徴でもある GraphQL の機能について紹介しました。
これまで触ったことがない人も、これをきっかけにお試しでもいいので使って貰えればと思います。