如何使用 Apollo 分离 GraphQL 模式和解析器文件?

Posted

技术标签:

【中文标题】如何使用 Apollo 分离 GraphQL 模式和解析器文件?【英文标题】:How to separate GraphQL schema and resolver files using Apollo? 【发布时间】:2020-09-28 22:32:16 【问题描述】:

我有这个简单的 GraphQL Apollo 服务器在一个文件中工作,但在将架构和解析器“模块化”到自己的文件时,我无法让它工作。

/index.js

require('dotenv').config()
const  MongoClient  = require('mongodb')
const  ApolloServer, makeExecutableSchema  = require('apollo-server')

const  Query  = require('./resolvers/Query')

// database connection
MongoClient.connect(process.env.DB_URL, 
  poolSize: 25,
  useUnifiedTopology: true,
  wtimeout: 2500
).catch(error => 
  console.log('Error connecting to MongoDB.', error.stack)
  process.exit(1)
).then(async client => 
  console.log(`Connected to database: $process.env.DB_NAME`)

  const dbConnection = client.db(process.env.DB_NAME)

  const resolvers = 
    Query
  

  const schema = makeExecutableSchema(
    typeDefs: './schema.graphql',
    resolvers
  )

  const server = new ApolloServer(
    schema: schema
  )

  server.listen().then(( url ) => 
    console.log(`Server ready at $url.`)
  )
)

/schema.graphql

type CourseType 
  _id: String!
  name: String!


type Query 
  courseType(_id: String): CourseType
  courseTypes: [CourseType]!

/resolvers/Query.js

const  ObjectId  = require('mongodb')

const courseTypesCollection = dbConnection.collection(process.env.DB_COLLECTION_COURSE_TYPES)

const Query = 
  courseType: async (root,  _id ) => 
    return courseTypesCollection.findOne(ObjectId(_id))
  ,
  courseTypes: async () => 
    return courseTypesCollection.find().toArray()
  


module.exports = 
  Query

当我尝试运行 index.js 文件时,我收到错误:UnhandledPromiseRejectionWarning: GraphQLError: Syntax Error: Cannot parse the unexpected character "."。这似乎我没有正确加载/使用模式文件。如果apollo-server 可以自行处理,我希望在不添加更多库的情况下使其正常工作。

【问题讨论】:

请一次只问一个问题。您的第二个问题与第一个问题无关,应单独发布。 @TalZ 抱歉,第二个问题已删除。 【参考方案1】:

makeExecutableSchema 期望 typeDefs 是类型定义的字符串,代表解析为 AST 的类型定义的 DocumentNode 对象,前者的数组将被合并在一起。在这里,您似乎将文件路径传递给typeDefs,而不是文件的内容。

您可以将/schema.graphql 文件更改为一个简单的代码文件,例如:

const schema = `
  type CourseType 
    _id: String!
    name: String!
  

  type Query 
    courseType(_id: String): CourseType
    courseTypes: [CourseType]!
  
`
module.exports = schema

然后将其加载到 typedef

  const graphQLSchema = require('./schema.graphql')
  //...

  const schema = makeExecutableSchema(
    typeDefs: graphQLSchema,
    resolvers
  )

如果您将数组传递给typeDefs,您可以通过这种方式加载多个模式

【讨论】:

谢谢!不知道typeDefs 只是在寻找一个字符串。问题:是否有来自apollo-server 的方法可以解析架构的.graphql 文件,而不必将schema.graphql 封装为字符串? 我不知道是否有内置方法,但是您可以使用fs.readFile(...)自己轻松做到这一点

以上是关于如何使用 Apollo 分离 GraphQL 模式和解析器文件?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL - 将 .graphql 模式导入为 typeDefs

Graphql - Apollo 服务器 - 热更新模式

如何在 GraphQL 和 Apollo 中部分模拟模式?

如何使用 apollo / graphql 实现节点查询解析器

(Apollo) GraphQL 合并模式

如何立即触发 apollo graphql 订阅?