技術日誌

野球関係のサービスを個人開発しています。

NodeJSでGraphQLのサーバ側処理を実装してみる

背景

先週はクライアントからGraphQLへのアクセス方法を学習しました。

今週は「サーバサイドはどう実装するのか?」という部分を調査しました。

パッケージインストール

今回は既に実装しているアプリケーションサーバにgraphqlを組み込みます。

$ npm install graphql express-graphql -save

スキーマ定義

jsonでもtypescriptでもないので一旦外部ファイル(graphql/schema.graphql)として定義しました。 graphqlに対応しているlintとかあるみたいなのですが、 今回は調査が追いついていません。

Queryタイプに型とクエリを定義する

id(選手ID)でフィルタリングしてPlayer(選手)を返すクエリと players(選手リスト)を返すクエリを想定します。 Playerオブジェクトは以下のようなプロパティを持つとします。 DBからデータを取得して返却する際にプロパティ同士がマッピングされます。

type Query {
  player(id: Int!): Player
  players(name: String): [Player]
},
type Player {
  id: Int
  name: String
  team_name :String
  team_id: Int
}

エンドポイントの作成

  • スキーマを外部ファイルから読み込む
  • buildSchemaに渡してスキーマを生成する
  • express_graphqlに
    • 第一引数にスキーマ
    • 第二引数にメソッド定義
    • 第三引数はAPIエンドポイントでGraphiQL(GUI)を動かせるようにするかどうか

を渡す。

App.ts

import { graphql} from './graphql'
import * as express_graphql from 'express-graphql';
import { buildSchema } from 'graphql';
(中略)
let schemaStr = readFileSync('./graphql/schema.graphql',{encoding:'utf8'})
var schema = buildSchema(schemaStr);
let root = {
  player:(args)=>{
      let result = new graphql().getPlayer(args)
      console.log(result)
      return result
  }
};
app.use('/graphql', express_graphql({
  schema: schema,
  rootValue: root,
  graphiql: true
 }));

メソッド実装

GraphQLの処理部分は分けて実装したかったので、別途graphql.tsを作ってそちらに実装します。

  • App.tsで定義したGraphQLのメソッド定義を書く

graphql.ts

import { playerService } from "../services/playerService";

export class graphql{
    public getPlayer(args:any):Promise<any>{
        return new Promise((resolve,reject)=>{
            (async()=>{
                //既存のDBアクセスメソッドにリクエストパラメータを渡す
                let player = await new playerService().findId(args.id)
                console.log(player)
                resolve(player[0])
             })()
             .catch((err)=>{
                 console.log(err)
                 reject(err)
             })
        })
    }
    
}

完成イメージ(動画)

参考リンク