LoginSignup
2
1

More than 5 years have passed since last update.

GraphQL fragment

Last updated at Posted at 2019-04-01

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のループを避けるため。

2
1
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
2
1