简体   繁体   English

如何在现有 GraphQL 服务器上添加根和查看器查询以支持中继

[英]How to add root and viewer queries on an existing GraphQL Server for Relay support

I've been working with GraphQL for a while and was able to successfully launch a simple GraphQL Server.我一直在使用 GraphQL,并且能够成功启动一个简单的 GraphQL 服务器。 Now I'm trying to make it support Relay, my final goal, and I'm having trouble adding support for the root node query and the viewer query.现在我试图让它支持 Relay,这是我的最终目标,但我在添加对根节点查询和查看器查询的支持时遇到了麻烦。

I do understand the concept of both node and viewer, but I'm not making it work in the way I've structured my code.我确实理解节点和查看器的概念,但我并没有按照我构建代码的方式使其工作。 Here is my code, organized into separate files:这是我的代码,组织成单独的文件:

./graphql/User/types.js ./graphql/User/types.js

import { 
    GraphQLObjectType, 
    GraphQLInputObjectType,
    GraphQLNonNull,
    GraphQLID,
    GraphQLList,
    GraphQLString, 
    GraphQLInt, 
    GraphQLBoolean 
} from 'graphql';

 import { GraphQLLong } from '../scalars';

 import { NodeInterface } from '../interfaces';

const fields = {
        _id: {
            type: new GraphQLNonNull(GraphQLID)
        },
        email: {
            type: GraphQLString
        },
        firstName: {
            type: GraphQLString
        },
        lastName: {
            type: GraphQLString
        },
        jobTitle: {
            type: GraphQLString
        },
        phone: {
            type: GraphQLString
        }
    };


export const UserType = new GraphQLObjectType({
    name: 'User',
    description: 'User',
    interface: NodeInterface,
    fields: fields
})

./graphql/User/queries.js ./graphql/User/queries.js

import { GraphQLNonNull, GraphQLID, GraphQLList } from 'graphql';

import { UserType, UserInputType } from './types';
import UserModel from '../../models/User';

const User = {
    type: UserType,
    description: 'Get single user',
    args: {
        id: {
            name: 'id',
            type: new GraphQLNonNull(GraphQLID)
        }
    },
    resolve(root, params) {

        params.deleted = false;

        return UserModel.find(params).exec();
    }
}


const Users = {
    type: new GraphQLList(UserType),
    description: 'Get all users',
    resolve(root) {
        const companies = UserModel.find({ deleted: false }).exec();
        if (!companies) {
            throw new Error('Error getting users.')
        }
        return companies;   
    }
}

export default {
    User,
    Users
}

./graphql/Company/types.js ./graphql/公司/types.js

import { 
    GraphQLObjectType, 
    GraphQLInputObjectType,
    GraphQLNonNull,
    GraphQLID,
    GraphQLList,
    GraphQLString, 
    GraphQLInt, 
    GraphQLBoolean 
} from 'graphql';

 import { GraphQLLong } from '../scalars';

 import { UserType } from '../User/types';

 import { NodeInterface } from '../interfaces';

 import UserModel from '../../models/User';

 const fields = {
    _id: {
        type: new GraphQLNonNull(GraphQLID)
    },
    name: {
        type: GraphQLString
    },
    ein: {
        type: GraphQLString
    },
    users: {
        type: new GraphQLList(UserType),
        resolve(company) {
            const { _id } = company;
            return UserModel.find({ companyId: _id }).exec();
        }
    }
 };

 export const CompanyType = new GraphQLObjectType({
    name: 'Company',
    description: 'Company',
    interface: NodeInterface,
    fields: fields
 })
 

./graphql/Company/queries.js ./graphql/Company/queries.js

import { GraphQLNonNull, GraphQLID, GraphQLList } from 'graphql';

import { CompanyType, CompanyInputType } from './types';
import CompanyModel from '../../models/Company';

const Company = {
    type: CompanyType,
    description: 'Get single company',
    args: {
        id: {
            name: 'id',
            type: new GraphQLNonNull(GraphQLID)
        }
    },
    resolve(root, params) {

        params.deleted = false;

        return CompanyModel.find(params).exec();
    }
}


const Companies = {
    type: new GraphQLList(CompanyType),
    description: 'Get all companies',
    resolve(root) {
        const companies = CompanyModel.find({ deleted: false }).exec();
        if (!companies) {
            throw new Error('Error getting companies.')
        }
        return companies;   
    }
}

export default {
    Company,
    Companies
}

./graphql/interfaces.js ./graphql/interfaces.js

import { 
    GraphQLInterfaceType,
    GraphQLNonNull, 
    GraphQLID 
} from 'graphql';


const NodeInterface = new GraphQLInterfaceType({
    name: 'Node',
    fields: {
        id: {
            type: new GraphQLNonNull(GraphQLID)
        }
    },
    resolveType: (source) => {

        return source.__type;
    }
});

export default NodeInterface;

./graphql/schema.js ./graphql/schema.js

import { GraphQLObjectType, GraphQLSchema } from 'graphql';
import queries from './queries';
import mutations from './mutations';


export default new GraphQLSchema({
    query: new GraphQLObjectType({
        name: 'Query',
        fields: queries
    }),
    mutation: new GraphQLObjectType({
        name: 'Mutation',
        fields: mutations
    })
});

./graphql/queries.js ./graphql/queries.js

import {
    GraphQLObjectType,
    GraphQLNonNull,
    GraphQLID
} from 'graphql';

import { NodeInterface } from './interfaces';
import CompanyQueries from './Company/queries';
import UserQueries from './User/queries';

const RootQuery = new GraphQLObjectType({

    name: 'RootQuery',
    description: 'The root query',
    fields: {
        viewer: {
            type: NodeInterface,
            resolve(source, args, context) {
                return { result: "VIEWER!" };
            }
        },
        node: {
            type: NodeInterface,
            args: {
                id: {
                    type: new GraphQLNonNull(GraphQLID)
                }
            },
            resolve(source, args, context, info) {
                return { result: "NODE QUERY" };
            }
        }
    }
});

export default {
    RootQuery,
    ...CompanyQueries,
    ...UserQueries
}

./server.js ./server.js

import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import morgan from 'morgan';
import graphqlHTTP from 'express-graphql';

import schema from './graphql/schema';

// set up example server
const app = express();
app.set('port', (process.env.API_PORT || 3001));


// logger
app.use(morgan('dev')); 

// parse body
app.use(bodyParser.json());

app.use('/graphql', graphqlHTTP({
    schema: schema,
    graphiql: true,
    pretty: true
}));

const mongoUri = process.env.MONGO_URI || 'mongodb://localhost/testdb';

mongoose.set('debug', true);

mongoose.connect(mongoUri, {
    useMongoClient: true,
});

export default app;

The RootQuery is not being added to Schema. RootQuery 没有被添加到架构中。 In fact I'm getting this error:事实上,我收到了这个错误:

Error: Query.RootQuery field type must be Output Type but got: undefined.

Conceptually I don't know how to fix this code:从概念上讲,我不知道如何修复此代码:

a) I don't know how to add that RootQuery to my query, and I don't know if I need to keep my other queries to my server (as Relay basically relies on node queries). a) 我不知道如何将该 RootQuery 添加到我的查询中,并且我不知道是否需要将其他查询保留到我的服务器上(因为 Relay 基本上依赖于节点查询)。

b) I cannot also see how my RootQuery will discover the object type and return it at the return source.__type . b) 我也看不到我的 RootQuery 将如何发现对象类型并在return source.__type处返回它。 I've added that piece of code but I don't know how or where the given type will fill up this field.我已经添加了那段代码,但我不知道给定的类型将如何或在何处填充此字段。

Although I'm understanding a little of GraphQL, it seems that I don't have yet the fundamentals on how to build the Relay required root query (not to talk about the paginators, but this is my next step once I solve that).虽然我对 GraphQL 有一些了解,但似乎我还没有关于如何构建 Relay 所需的根查询的基础知识(不要谈论分页器,但是一旦我解决了这个问题,这是我的下一步)。

The problem appears to be问题似乎是

import queries from './queries';

new GraphQLObjectType({
    name: 'Query',
    fields: queries
}),
const RootQuery = new GraphQLObjectType({
    …
});

export default {
    RootQuery,
    …
};

The queries that you pass as the fields for the Query type is an object of types, not an object of field configurations.所述queries您传递作为字段Query的类型是类型的对象,而不是场结构的一个对象。 They are missing type and resolve properties, as the error message complains.它们缺少typeresolve属性,因为错误消息抱怨。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM