
ショコラ
GraphQL について apollo-server版
前回は「express-graphql」を使いました。今回は「apollo-server」を使って同じことをしてみます。

もっさん先輩
GraphQL のはじめの一歩
- graphql をインストールします。
mkdir graphql-apollo
cd graphql-apollo
npm install apollo-server graphql
- サンプルプログラムを作成します。
const {ApolloServer,gql} = require('apollo-server')
const server = new ApolloServer({
// スキーマ定義
typeDefs:gql`
type Query {
test: String
}
`,
// リゾルバ(実装)
resolvers:{
Query:{
test:() => 'Hello Answorz!'
}
},
})
server.listen().then(({url,subscriptionsUrl}) => {
console.log(`Server ready at ${url}`)
console.log(`Subscriptions ready at ${subscriptionsUrl}`)
})
- graphqlサーバーを起動します。
node server.js
- URL にアクセスします。

ローカルホスト以外から http でアクセスすると↓以下のエラーが表示されます。ローカルホスト以外は https でアクセスしなければならないようです。
Network requests from Studio on HTTPS to your HTTP endpoint are not secure, so we cannot introspect your endpoint.
TeraTerm のポートフォワーディングを使って http://localhost:4000 でアクセスすることができます。

↓「OK」ボタンを押すと localhost:4000 でアクセスすることができます。

- 問い合わせます。
query {
test
}
test の結果が JSON で返ってきました。

配列を使ってみる。
const {ApolloServer,gql} = require('apollo-server')
const server = new ApolloServer({
// スキーマ定義
typeDefs:gql`
type Query {
test:[String]
}
`,
// リゾルバ(実装)
resolvers:{
Query:{
test() => ['Hello Answorz1!','Hello Answorz2!']
}
},
})
server.listen().then(({url,subscriptionsUrl}) => {
console.log(`Server ready at ${url}`)
console.log(`Subscriptions ready at ${subscriptionsUrl}`)
})
問い合わせ方は↓こちらです。
{
test
}

パラメーターを使ってみる。
↓パラメーターを使うポイントは、parent,args,context,info の引数から値を取得するところです。
const {ApolloServer,gql} = require('apollo-server')
const server = new ApolloServer({
// スキーマ定義
typeDefs:gql`
type Query {
test(ct:Int!):[Int]
}
`,
// リゾルバ(実装)
resolvers:{
Query:{
test:(parent,{ct},context,info) => {
let result = []
for (let i=0;i < ct;i++) {
result.push(Math.floor(Math.random() * 100))
}
return result
}
}
},
})
server.listen().then(({url,subscriptionsUrl}) => {
console.log(`Server ready at ${url}`)
console.log(`Subscriptions ready at ${subscriptionsUrl}`)
})
問い合わせ方は↓こちらです。
query {
test(ct:20)
}

クラスを使ってみます。
↓リゾルバに変数を渡すには、context に登録して、context から値を取得するようにします。
class Person {
id
name
age
constructor(id,name,age) {
this.id = id
this.name = name
this.age = age
}
}
let db = {}
db[1] = new Person(1,'もっさん',40)
db[2] = new Person(2,'ショコラ',10)
const {ApolloServer,gql} = require('apollo-server')
const server = new ApolloServer({
// スキーマ定義
typeDefs:gql`
type Person {
id:ID
name:String
age:Int
}
type Query {
getPerson(id:ID!):Person
}
`,
// リゾルバ(実装)
resolvers:{
Query:{
getPerson:(parent,args,{db},info) => db[args.id]
}
},
context:{
db
}
})
server.listen().then(({url,subscriptionsUrl}) => {
console.log(`Server ready at ${url}`)
console.log(`Subscriptions ready at ${subscriptionsUrl}`)
})
問い合わせをする場合、↓下のように取得するフィールドを指定します。カンマ必要無し。
query {
getPerson(id:2) {
id
name
age
}
}

データを登録してみる。
この場合使うのが「type Mutation」です。
class Person {
id
name
age
constructor(id,name,age) {
this.id = id
this.name = name
this.age = age
}
}
let db = {}
const {ApolloServer,gql} = require('apollo-server')
const server = new ApolloServer({
// スキーマ定義
typeDefs:gql`
type Person {
id:ID
name:String
age:Int
}
type Query {
getPerson(id:ID!):Person
}
type Mutation {
createPerson(id:ID!,name:String!,age:Int!): Person
updatePerson(id:ID!,name:String!,age:Int!): Person
}
`,
// リゾルバ(実装)
resolvers:{
Query:{
getPerson:(parent,{id},{db},info) => db[id],
},
Mutation:{
createPerson:(parent,{id,name,age},{db},info) => db[id] = new Person(id,name,age),
updatePerson:(parent,{id,name,age},{db},info) => db[id] = new Person(id,name,age),
}
},
context:{
db
}
})
server.listen().then(({url,subscriptionsUrl}) => {
console.log(`Server ready at ${url}`)
console.log(`Subscriptions ready at ${subscriptionsUrl}`)
})
Mutation で登録します。
mutation {
createPerson(id:1,name:"もっさん",age:40) {
id
name
age
}
}
mutation {
createPerson(id:2,name:"ショコラ",age:10) {
id
name
age
}
}
問い合わせをしてみます。
query {
getPerson(id:1) {
id
name
age
}
}

query {
getPerson(id:2) {
id
name
}
}

データをクラスで登録してみる。
↓クラスでデータを登録するとき定義で使うのが input。PersonInput に注目です。
class Person {
id
name
age
constructor(id,name,age) {
this.id = id
this.name = name
this.age = age
}
}
let db = {}
const {ApolloServer,gql} = require('apollo-server')
const server = new ApolloServer({
// スキーマ定義
typeDefs:gql`
type Person {
id:ID
name:String
age:Int
}
input PersonInput {
id:ID
name:String
age:Int
}
type Query {
getPerson(id:ID!):Person
}
type Mutation {
createPerson(input:PersonInput): Person
updatePerson(input:PersonInput): Person
}
`,
// リゾルバ(実装)
resolvers:{
Query:{
getPerson:(parent,{id},{db},info) => db[id],
},
Mutation:{
createPerson:(parent,{input},{db},info) => db[input.id] = input,
updatePerson:(parent,{input},{db},info) => db[input.id] = input,
}
},
context:{
db
}
})
server.listen().then(({url,subscriptionsUrl}) => {
console.log(`Server ready at ${url}`)
console.log(`Subscriptions ready at ${subscriptionsUrl}`)
})
Mutation で登録します。
mutation {
createPerson(input:{
id:1
name:"もっさん"
age:40
}) {
id
name
age
}
}
mutation {
createPerson(input:{
id:2
name:"ショコラ"
age:10
}) {
id
name
age
}
}
変数を使って登録してみます。
mutation ($input:PersonInput!) {
createPerson(input:$input) {
id
name
age
}
}
{
"input":{
"id":3,
"name":"ナイスガイ",
"age":20
}
}
今回は変数を使って問い合わせをしてみます。
query ($id:ID!) {
getPerson(id:$id) {
id
name
}
}
{"id":1}

以上