fragment
fragment ⇒ どこでも使える Selection Set。クエリ時に Selection Set を強制することもできる。
例えば、以下のようなResolverを考える。
User.js
const User = {
email: {
resolve(parent, args, { request }, info) {
// JWT token 処理をして userId を取得
const userId = getUserId(request, false)
// tokenをdecodeして取得した userId とDB内の userId が一致することを確認
// つまりDB内の自分のemailだけ確認ができるということ
if(userId && userId === parent.id) {
return parent.email
} else {
return null
}
}
}
}
export { User as default }
ここで userId が一致することを確認しているが、これはGraphQLクエリの Selection Set に id が含まれていないと成り立たない。そこで、如何なる場合も Selection Set に id を強制的に含ませるように fragment を使用する。
User.js
const User = {
email: {
fragment: 'fragment userId on User { id }', // ここ!
resolve(parent, args, { request }, info) {
const userId = getUserId(request, false)
if(userId && userId === parent.id) {
return parent.email
} else {
return null
}
}
}
}
export { User as default }
resolvers/index.js
import { extractFragmentReplacements } from 'prisma-binding'
import Query from './Query'
import User from './User'
const resolvers = {
Query
User
}
// resolverファイルで定義したfragmentを抽出
const fragmentReplacements = extractFragmentReplacements(resolvers)
export { resolvers, fragmentReplacements }
src/index.js
import '@babel/polyfill/noConflict'
import { GraphQLServer, PubSub } from 'graphql-yoga'
import db from './db'
import { resolvers, fragmentReplacements } from './resolvers/index' // ここ!
import prisma from './prisma'
const pubsub = new PubSub()
const server = new GraphQLServer({
typeDefs: './src/schema.graphql',
resolvers,
context(request) {
return {
db,
pubsub,
prisma,
request
}
},
fragmentReplacements // ここ!
})
server.start({ port: process.env.PORT || 4000 }, () => {
console.log('The server is up!')
})
prisma.js
import { Prisma } from 'prisma-binding'
import { fragmentReplacements } from './resolvers/index' // ここ!
const prisma = new Prisma({
typeDefs: 'src/generated/prisma.graphql',
endpoint: process.env.PRISMA_ENDPOINT,
secret: process.env.PRISMA_SECRET,
fragmentReplacements // ここ!
})
export { prisma as default }
これで必ず id が含まれるようになる。
※ わざわざ resolvers/index.js を作成することで、src/index.js と prisma.js のどちらも fragmentReplacements をimportできるようにしている。importのループを避けるため。