GraphQLで、電脳少女シロちゃんの`オホー報`を取得するスキーマを作ってみる

## 概要
GraphQLの入門がてら、シロちゃんの`オホー報`を取得するスキーマを作るまで

#### `オホー報`とは
:dolphin:[**電脳少女シロちゃん**](https://www.youtube.com/channel/UCLhUvJ_wO9hOvv_yYENu4fQ):dolphin:が、自身のTwitterにて呟くやんごとなき告知
![oho1.PNG](https://qiita-image-store.s3.amazonaws.com/0/119363/1ca6a33a-2172-5320-150a-5af7e6d5d067.png)
![oho2.PNG](https://qiita-image-store.s3.amazonaws.com/0/119363/6220b6a5-e70e-3115-0313-4b521a8f20e9.png)
~~シロちゃんかわいいよシロちゃん~~

## やってみる

### GraphQLサーバー構築
- node.js 8.x～
 - [**express**](https://www.npmjs.com/package/express)及び[**express-graphql**](https://github.com/graphql/express-graphql)でGraphQLサーバー構築

```sh
npm init
npm i express express-graphql
```

```sh
vi server.js
```
```javascript:server.js
const express = require('express')
const expressGraphQl = require('express-graphql')
const {buildSchema} = require('graphql')

const schema = buildSchema(`
  type Query {
    hoge : String
  }
`)

const app = express()
app.use('/graphql', expressGraphQl({
  schema,
  rootValue : {
   hoge : () => 'hello! graphql!'
  },
  graphiql : true
}))

app.listen(80, () => console.log('running graphql server.'))
```

`node server.js`でGraphQLサーバーが立ち上がります
`http://<<ホスト名>>/graphql`にブラウザでアクセスすると、GraphQLサーバー及びGraphQLクライアント(web)アプリが立ち上がっている事が確認出来ます
![graphql.PNG](https://qiita-image-store.s3.amazonaws.com/0/119363/3378967f-b3f5-727c-a316-7ba6c5758843.png)
あっさりGraphQLサーバーが構築出来ましたね~~express-graphqlやりおるマン~~

### シロちゃんのツイートを取得
 - twitter APIにアクセスするための認証情報を設定

```json:authInfo.json
{
  "consumer_key" : "your consumer_key",
  "consumer_secret" : "your consumer_secret",
  "access_token_key" : "your access_token_key",
  "access_token_secret" : "your access_token_secret"
}

```
- node moduleのTwitterクライアントでツイートを取得

```sh
npm i twitter
```

```javascript:twitter.js
const Twitter = require('twitter')
const AuthInfo = require('./authInfo')
const client = new Twitter(AuthInfo)

module.exports.getTweet = ({target}) => {
  const param = {
    screen_name : target, // ★twitterで見かける『@』から始まるｱﾚ
    count : 200
  }

  return new Promise((resolve, reject) => {
    client.get('statuses/user_timeline', param, (error, tweets, response) => {
      if(error) {
        return reject(error, response)
      }

      resolve(tweets, response)
    })
  })
}

```

```javascript
const twitter = require('./twitter.js')

twitter
 .getTweet({// ツイート情報取得(最大直近200件)
  target : 'SIROYoutuber' // ★twitterで見かける『@』から始まるｱﾚ
 })
 .then(tweets => console.table(tweets)) // ツイート情報ログ表示(取得に成功した場合)
```

### `オホー報`を取得するスキーマを定義

```javascript:server.js
const express = require('express')
const expressGraphQl = require('express-graphql')
const {buildSchema} = require('graphql')

const twitter = require('./twitter/twitter.js')

const schema = buildSchema(`
  type Query {
    ohoHou : [String]
  }
`)

const ohoHou = twitter // ツイート情報(配列、構造体)から【オホー報】を抽出
                .getTweet({target : 'SIROyoutuber'})
                .then(tweets => tweets.map(tweet => tweet.text))
                .then(texts => texts.filter(text => text.match(/【オホー報】/)))

const app = express()
app.use('/graphql', expressGraphQl({
  schema,
  rootValue : { ohoHou },
  graphiql : true
}))

app.listen(80, () => console.log('running graphql server.'))
```

サーバーをスタート

```sh
node server.js
```

クライアントアプリから『オホー報クエリ』(**ohoHou**)を発行してみましょう

```graphql:query
{
 ohoHou
}
```

![ohoQuery.PNG](https://qiita-image-store.s3.amazonaws.com/0/119363/a6b6b42c-3e07-7230-684d-be2b5d08770d.png)
無事取得出来ました!

### やってみて(技術的な感想)
rootValueの返却値に、**Promise<resolve or reject>な値**をそのまま定義出来てちょっと感動
 
- 普通(?)の値はこう

```javascript
const schema = buildSchema(`
  type Query {
    hogeText : String
  }
`)

const app = express()
/** 
   {
    hogeText
   }
   クエリを発行すると // クエリ
   'hogehoge!'が取得される
**/
app.use('/graphql', expressGraphQl({
  schema,
  rootValue : { 
   hogeText : () => 'hogehoge!'
  },
  graphiql : true
}))
```

 - Promise型な値はこう引き渡す


```javascript
const schema = buildSchema(`
  type Query {
    hogeText : String
  }
`)

const app = express()
/** 
   {
    hogeText // クエリ
   }
   クエリを発行すると 
   'Promise hogehoge!'が取得される
**/
app.use('/graphql', expressGraphQl({
  schema,
  rootValue : { 
   hogeText : new Promise((resolve, reject) => resolve('Promise hogehoge!'))
  },
  graphiql : true
}))
```
javascriptお馴染みである非同期取得した値も、非常に直観的に扱えてgoodです!


### やってみて(雑多な感想)
- 直近200件のツイートからしか取得が出来なかった。twitter apiの仕様(?)なのでどうしようもないんだろうかという若干の消化不良感
 - その辺りもあまり詳しくないので、 ご存知の方はご指摘頂けると幸いです
- 単純すぎて、GraphQLでやる意味が正直薄い要件だったな、とは思ってる…
- ただこんなﾁｬﾁい物でも、実際に手を動かして作ってみる事によって、**これがGraphQLか!感**を軽く掴めた気がする~~シロちゃんのオホー報は為になるなぁ!~~
 - 今回を足掛かりに、次はもっと(GraphQLの旨味を活かせるような)応用的な某かを作りたいと思った
     - **GraphQL面白い!**:grin:

### ソース
[githubに上げてます](https://github.com/nishiurahiroki/sirochan-ohohou-schema)