Expressとexpress-graphqlで簡易なGraphQLサーバーを立てる


Expressとexpress-graphqlで簡易なGraphQLサーバーを立てることについては、
すべてGraphQL.js公式に書いてあります(じゃあなんでこの記事書くんだ)

Getting Started With GraphQL.js
https://graphql.org/graphql-js/
Running an Express GraphQL Server
https://graphql.org/graphql-js/running-an-express-graphql-server/

その前に、段階を踏んでGraphQLクエリが試せるこちらの記事を最初にやってみるのがおすすめです(npmモジュールは違うもの使ってる)

Web API初心者と学ぶGraphQL
https://qiita.com/SiragumoHuin/items/cc58f456bc43a1be41b4

下記コードも、GraphQL.js公式のものに少し処理(引数やらforやら)を加えているので、やっぱり公式を見ていただいた方がわかりやすいです(じゃあなんでうんぬん)

概要

・express,express-graphql,ngraphqlをインストール
・graphqlからbuildSchemaをrequireして、スキーマを定義
・クエリごとに関数を定義してrootオブジェクトにまとめる
・express-graphqlからgraphqlHTTPをrequireして、expressルーターにマウントする。
(shemaにbuildSchemaで定義したスキーマを、rootValueにrootオブジェクトを設定し、graphiql(クエリ試せるツール)はtrueにする)
・サーバーを立てる

コード

index.js
const express = require("express");
const { graphqlHTTP } = require("express-graphql");
const { buildSchema } = require("graphql");

const schema = buildSchema(`
  type Query {
    hello(persons: [String]): [Text]
  },
  type Text {
    text1: String,
    text2: String
  },
`);

const root = {
  hello: ({ persons }) => {
    let text = [];
    for (const person of persons) {
      let hash = {
        text1: "Hello world !",
        text2: `Hello, ${person}さん!`
      };
      text.push(hash);
    }
    return text;
  },
};

const app = express();
app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
  })
);
app.listen(4000);
console.log("Running a GraphQL API server at http://localhost:4000/graphql");

クエリは、node index.jsでサーバーを立てると、GraphiQLというクエリをブラウザ上で試せるツールが立ち上がるので、その入力欄に

query {
  hello(persons: ["tarou", "hanako"]) {
    text1
    text2
  }
}

と入力すれば、

{
  "data": {
    "hello": [
      {
        "text1": "Hello world !",
        "text2": "Hello, tarouさん!"
      },
      {
        "text1": "Hello world !",
        "text2": "Hello, hanakoさん!"
      }
    ]
  }
}

と返ってきます。

curlだとこんなかんじ。

$ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ hello(persons: [\"tarou\", \"hanako\"]) { text1 text2 } }" }' http://localhost:4000/graphql