11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GraphQL.jsのチュートリアルをただやってみただけの投稿

Posted at

私は初心者です。こちらのチュートリアルをみながら自分で試したことをただメモ用に書いていくだけです。よろしくお願いいたします。

Getting Started With GraphQL.js | GraphQL.js Tutorial


Getting Started With GraphQL.js

GraphQL.js のインストール

yarn add graphql
server.js
const { graphql, buildSchema } = require('graphql');

// GraphQLスキーマ言語を使用して、スキーマを構築
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

// ルートは各APIエンドポイントにリゾルバー機能を提供する
const root = {
  hello: () => {
    return 'Hello world!';
  },
};

// GraphQLクエリ '{ hello }' を実行してレスポンスを出力
graphql(schema, '{ hello }', root).then((response) => {
    console.log(response);
});
$ node server.js 
{ data: [Object: null prototype] { hello: 'Hello world!' } }

Running an Express GraphQL Server

expressで実行するために必要なライブラリをインストール

yarn add express express-graphql graphql

apiサーバ作成

server.js
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');

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

const root = {
  hello: () => {
    return 'Hello world!';
  },
};

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 server.js 
Running a GraphQL API server at http://localhost:4000/graphql

graphiql: true としたので、graphiql を使用できます

Screen Shot 2020-03-21 at 17.06.55.png

GraphQL Clients

  • curlでgraphqlを実行する
$ curl -X POST -H "Content-Type: application/json" -d '{"query": "{ hello }"}' http://localhost:4000/graphql
{"data":{"hello":"Hello world!"}}
  • GUIで実行する場合はGraphiQLInsomniaなどを使う

  • ブラウザから実行する

http://localhost:4000/graphql のdevtoolを開いて、以下をコピペする

fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({query: "{ hello }"})
})
  .then(r => r.json())
  .then(data => console.log('data returned:', data));
Screen Shot 2020-03-22 at 19.19.00.png

Basic Types

GraphQLスキーマ言語は、String、Int、Float、Boolean、およびIDのスカラータイプをサポートしているため、buildSchemaに渡すスキーマでこれらを直接使用できます。

デフォルトでは、すべての型はnull値を許可します。スカラー型のいずれかとしてnullを返すことは正当です。 感嘆符を使用して、型をnullにできないことを示すため、String! null不可の文字列です。

const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');

const schema = buildSchema(`
  type Query {
    quoteOfTheDay: String
    random: Float!
    rollThreeDice: [Int]
  }
`);

const root = {
  quoteOfTheDay: () => {
    return Math.random() < 0.5 ? 'Take it easy' : 'Salvation lies within';
  },
  random: () => {
    return Math.random();
  },
  rollThreeDice: () => {
    return [1, 2, 3].map(_ => 1 + Math.floor(Math.random() * 6));
  },
};

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

指定の型で取得できたことを確認できました

Screen Shot 2020-03-22 at 19.40.20.png

Passing Arguments

numDiceとnumSidesを引数にとるrollDiceを定義

type Query {
  rollDice(numDice: Int!, numSides: Int): [Int]
}
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');

const schema = buildSchema(`
  type Query {
    rollDice(numDice: Int!, numSides: Int): [Int]
  }
`);

const root = {
  rollDice: ({numDice, numSides}) => {
    const output = [];
    for (let i = 0; i < numDice; i++) {
      output.push(1 + Math.floor(Math.random() * (numSides || 6)));
    }
    return output;
  }
};

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

引数付きで遅れることを確認

Screen Shot 2020-03-22 at 19.53.24.png

コードで引数を設定するときは、$構文を使う方が良い

const dice = 3;
const sides = 6;
const query = `query RollDice($dice: Int!, $sides: Int) {
  rollDice(numDice: $dice, numSides: $sides)
}`;

fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({
    query,
    variables: { dice, sides },
  })
})
  .then(r => r.json())
  .then(data => console.log('data returned:', data));
Screen Shot 2020-03-22 at 20.00.27.png

Object Types

オブジェクトタイプを指定して、値を返すようにします

server.js
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');

const schema = buildSchema(`
  type RandomDie {
    numSides: Int!
    rollOnce: Int!
    roll(numRolls: Int!): [Int]
  }

  type Query {
    getDie(numSides: Int): RandomDie
  }
`);

class RandomDie {
  constructor(numSides) {
    this.numSides = numSides;
  }

  rollOnce() {
    return 1 + Math.floor(Math.random() * this.numSides);
  }

  roll({numRolls}) {
    const output = [];
    for (let i = 0; i < numRolls; i++) {
      output.push(this.rollOnce());
    }
    return output;
  }
}

const root = {
  getDie: ({numSides}) => {
    return new RandomDie(numSides || 6);
  }
}

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
{
  getDie(numSides: 6) {
    numSides
    rollOnce
    roll(numRolls: 3)
  }
}
Screen Shot 2020-03-22 at 20.17.26.png

Mutations and Input Types

データの作成や更新はqueryではなくmutatisonで送る。
スキーマを簡単にするために、typeキーワードの代わりにinputキーワードを使用すると良いようです。

server.js
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');

const schema = buildSchema(`
  input MessageInput {
    content: String
    author: String
  }

  type Message {
    id: ID!
    content: String
    author: String
  }

  type Query {
    getMessage(id: ID!): Message
  }

  type Mutation {
    createMessage(input: MessageInput): Message
    updateMessage(id: ID!, input: MessageInput): Message
  }
`);

class Message {
  constructor(id, {content, author}) {
    this.id = id;
    this.content = content;
    this.author = author;
  }
}

const fakeDatabase = {};

const root = {
  getMessage: ({id}) => {
    if (!fakeDatabase[id]) {
      throw new Error('no message exists with id ' + id);
    }
    return new Message(id, fakeDatabase[id]);
  },
  createMessage: ({input}) => {
    const id = require('crypto').randomBytes(10).toString('hex');

    fakeDatabase[id] = input;
    return new Message(id, input);
  },
  updateMessage: ({id, input}) => {
    if (!fakeDatabase[id]) {
      throw new Error('no message exists with id ' + id);
    }
    fakeDatabase[id] = input;
    return new Message(id, input);
  },
};

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

データ作成を確認

Screen Shot 2020-03-22 at 20.32.59.png

データ更新を確認

Screen Shot 2020-03-22 at 20.34.59.png
11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?