Gridsome入門 SPAを作ってみよう 【5日目 GraphQL編】

# スケジュール
- [1日目 要件定義編](https://qiita.com/Dev-kenta/items/b5c8ea6b432fe3594282)
- [2日目 環境構築編](https://qiita.com/Dev-kenta/items/6ae251a648e04b9cf026)
- [3日目 ドーナッツグラフ編](https://qiita.com/Dev-kenta/items/9e141767c42deee743c8)
- [4日目 棒グラフ編](https://qiita.com/Dev-kenta/items/780c3cb4a4d0cf813824)
- [5日目 GraphQL編](https://qiita.com/Dev-kenta/items/1d08ef27aa877cfb6771)←今ここ
- [6日目 GraphQL編2](https://qiita.com/Dev-kenta/items/e4281380da38f57495b6)
- [7日目 GraphQL編3](https://qiita.com/Dev-kenta/items/1bf6dc021ec08932233c)
- [8日目 GraphQL編4](https://qiita.com/Dev-kenta/items/fcc65b0106ba29626db7)
- [9日目 デプロイ編](https://qiita.com/Dev-kenta/items/14ae9fdc6eec76f63ba1)

# 前提条件
- node.js v8.3以上
- yarn or npmが入っている(Document見るとyarnの方が推奨とのこと)
- Gridsomeのプロジェクトを作成している

# CSVからデータをインポートする
CSV用意してデータソースとして使用します。今回はCSVを使いますが、markdownで書かれたファイルなども使ったりできます。
https://gridsome.org/docs/fetching-data/#csv

```vuejs:gridsome.server.js
// Server API makes it possible to hook into various parts of Gridsome
// on server-side and add custom data to the GraphQL data layer.
// Learn more: https://gridsome.org/docs/server-api/

// Changes here require a server restart.
// To restart press CTRL + C in terminal and run `gridsome develop`

const {readFileSync} = require('fs');
const parse = require('csv-parse/lib/sync');
module.exports = function (api) {
  api.loadSource(async (actions) => {
    // インポートするCSV
    const input = readFileSync('./src/data/assetbalance_202008.csv', 'utf8');

    const Assets = parse(input, {
      from_line: 2,
      skip_empty_lines: true,
    });

    const collection = actions.addCollection({
      typeName: 'Assets',
    });

    for (const asset of Assets) {
      collection.addNode(asset);
    }
  })

  api.createPages(({ createPage }) => {
    // Use the Pages API here: https://gridsome.org/docs/pages-api/
  })
}
```

```/src/data/``` ディレクトリにインポートしたいCSVを配置します。
今回インポートするCSVは一行目は飛ばして、二行目からインポートするようにしました。

そしてインポートしたデータを```actions.addCollection``` コレクションとして追加して、そのコレクションに```collection.addNode(asset);``` として追加していくことでGraphQLを使ってデータを扱うことができるようになります。

## GraphQLとは
<img width="630" alt="import-data.eb9be63.3e0083b3c8c40a300ab593b006f88025.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402204/4c948dd4-fd81-0db6-2a0e-58bfa6c2f02e.png">
画像は https://gridsome.org/docs/data-layer/#the-graphql-data-layer より引用
僕も今勉強中ですが、様々なデータソースを吸収してGraphQLを使うと便利って感じですかね。
GraphQLはAPI用のクエリ言語として開発されたっていう経緯があるみたいです。

## 実際にGraphQLを使ってみよう
GridsomeにはGraphQLを試せるplaygroundが用意されています。これがすごい便利。
僕みたいな初見な人でも調べながら試しながらできるのですごい助かります。
playgroundは```gridsome develop``` を実行して、http://localhost:8080/___explore でアクセスできます。
![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402204/96d05c86-b332-6d83-6261-3f804af1f55b.png)
こんな感じの画面が表示されます。
左のクエリエディター？の画面に実行したいクエリを書いて、再生ボタンっぽいところを押すとクエリが実行されます。
GraphQLについてはこちらを参照
https://graphql.org/
もしくはplaygroundで右側についてるDOCSを開くと、実行しているクエリについても仕様を見ることができます。
![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402204/6217fcbb-dcb6-7ed3-b58b-86231cdc6574.png)

### 実際に作ったクエリ
```GraphQL
query {
  tickers: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _1
      }
    }
  }
  valuations: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _4
        _8
      }
    }
  }
}
```
filterの指定が難しかった。色々調べてできました。
nodeの中身が一つ一つのデータなのですが、CSVの一列目が_0,二列目が_1...みたいに追加されています。
filterで_0の値が米国株式となっているものだけ取得するという形にしています。eqがイコールですね。
他にもne(not イコール)などもありました。
<img width="1322" alt="image03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402204/84ca30ad-ea97-b6c3-86fd-c41fec45a410.png">

# GraphQLを使ってフロントエンドの処理に渡す
次は作ったクエリを実際に各ページで使うようにします。

```vuejs:src/pages/portfolio/index.vue
<template>
  <Layout>
    <h1>Portfolio</h1>
    <Doughnut :labels="this.formatLabels($page.tickers.edges)" :chartData="this.formatChartData($page.valuations.edges)"></Doughnut>
  </Layout>
</template>
<page-query>
query {
  tickers: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _1
      }
    }
  }
  valuations: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _4
        _8
      }
    }
  }
}
</page-query>
<script>
import Doughnut from "../../components/chart/Doughnut"
export default {
  components: {
    Doughnut
  },
  methods: {
    formatLabels: function (labels) {
      return labels.map(item => item['node']['_1']);
    },
    formatChartData: function (chartData) {
      return chartData.map(item => item['node']['_4'] * item['node']['_8']);
    }
  },
  metaInfo : {
    title: 'Hello, world!'
  }
}
</script>

<style>
.home-links a {
  margin-right: 1rem;
}
</style>
```

```<page-query>``` というタグの中にGraphQLのクエリを書きます。そしてフロントエンドの処理に渡すには$pageという名前でアクセスできます。
前回までに作ったグラフのcomponentsには配列で渡しているので、配列に直すmethodsも作りました。

# あとがき
いよいよお盆休みも折り返し。残り半分かー。早い。
そしてお盆休みなのに一日一回は仕事のslackくるのなに。。