Graphql查询返回空值(Apollo Server)

时间:2017-07-05 15:31:40

标签: node.js express graphql es6-modules apollo-server

我以编程方式创建了一个模拟用于在我的查询中进行测试,但它只返回一个空值,我做错了什么。我正在使用临时库为我的模拟

生成值

以下是我的文件:

index.js

   import express from 'express'
import bodyParser from 'body-parser'
import { graphqlExpress,graphiqlExpress } from 'graphql-server-express'
import { makeExecutableSchema } from 'graphql-tools'
import mock from './mock'
import schema from './schema'
const app = express()
const executableSchema = makeExecutableSchema({
    typeDefs: schema,
    mock
})

app.post(
    '/graphql',
    bodyParser.json(),
    graphqlExpress(() => ({
        schema: executableSchema
    }))
)

app.use('/graphiql',graphiqlExpress({
    endpointURL: '/graphql',
}))
app.listen(8080)
console.log("listening at 8080")

schema.js

const schema = `
interface Novel {
    artist: String
    author: String
    chapters: [Chapter]
    description: String
    genre: [String]
    id: String
    image: String
    language: String
    modified: String!
    name: String!
    status: String
    tags: [String]
    type: String
    year: String
}

interface Chapter {
chapter: String!
volume: String!
content: String!
}

type NovelCrawler implements Novel{
    artist: String
    author: String
    chapters: [Chapter]
    description: String
    genre: [String]
    id: String
    image: String
    language: String
    modified: String!
    name: String!
    novelurl: String
    status: String
    tags: [String]
    type: String
    year: String
}

type ChapterCrawler implements Chapter {
    chapter: String!
    chapterurl: String
    content: String!
    novelurl: String
    volume: String!
}
`
const Query = `
type Query {
     novels: [Novel]
}
`
export default [schema, Query]

mock.js

import casual from 'casual'
const genre = ['romance', 'comedy', 'action']
const Novel = () => ({
    artist: casual.name,
    author: casual.name,
    description: casual.sentences(3),
    genre: [casual.random_element(genre), casual.random_element(genre)],
    id: casual.url,
    image: 'sdfgrtw3wedfgb2345y675trfdvfbghdsfdssfd',
    language: casual.random_element(['chinese', 'japanese', 'korean']),
    modified: casual.date('YYYY-MM-DD'),
    name: casual.word,
    status: casual.random_element(['Completed', 'Ongoing']),
    tags: [],
    novelurl: casual.url,
    type: casual.random_element(['Web Novel', 'Light Novel']),
    year: casual.year
})

const Chapter = () => ({
    chapter: casual.integer(1, 50),
    chapterurl: casual.url,
    content: casual.sentences(10),
    novelurl: casual.url,
    volume: casual.integer(1, 5)
})

const arrNovel = []
const arrChapter = []
for (let x = 0; x < 20; ++x) {
    arrNovel.push(Novel())
    arrChapter.push(Chapter())
}

const mock = {
    // Query: { novels: () => ({}) },
    Novel: {
        __resolveType(obj, context, info) {
            return 'NovelCrawler'
        }
    },
    Chapter: {
        __resolveType(obj, context, info) {
            return 'ChapterCrawler'
        }
    },
    NovelCrawler: () => arrNovel,
    ChapterCrawler: () => arrChapter
}

export default mock

当我运行以下查询时:

{
  novels{
    description
  }
}

它返回:

{
  "data": {
    "novels": null
  }
}

所以我试过了:

{
 novels{
 ... on NovelCrawler{
  artist
    }
  }
 }

返回

 {
  "errors": [
    {
      "message": "Unknown operation named \"null\"."
    }
  ]
}

我做错了什么

1 个答案:

答案 0 :(得分:3)

感谢您提供完整的代码和示例。这里有一些注意事项可以帮助您朝着正确的方向前进:

  1. 确保正确实现模拟。我认为makeExecutableSchema过去常常接受一个模拟选项,但现在你必须结合使用addMockFunctionsToSchema来实现模拟。我会阅读Apollo's guide to mocking了解如何执行此操作的详细步骤。

  2. graphqlExpress实际上是中间件,因此您应该使用app.use而不是app.post来实现它。 GraphQL Server可以处理POST和GET请求。

  3. 您可能不需要接口来处理您正在尝试的操作。接口要求实现它的每个类型都具有接口中定义的字段。当两种或更多类型共享字段时使用它们,而这不是这种情况。我建议将Chapter作为常规类型并将其嵌套在ChapterCrawler内,如下所示。小说同上。

    type ChapterCrawler {
      chapter: Chapter!
      chapterurl: String
      novelurl: String   
    }
    type Chapter {
      chapter: String!
      content: String!
      volume: String!    
    }
    
  4. 如果您使用上述方法,则需要最终更改查询以取代[NovelCrawler]等等!在让事情变得更复杂和更难调试之前,我建议仅仅Chapter进行模拟并添加查询以获取[Chapters] 第一个。一旦你有了这个工作,你就会知道你已经掌握了基本的功能,并且可以开始模拟和查询更复杂的数据结构。

  5. 如果您确实需要接口,请确保获得它们所服务的功能以及如何正确实现它们。 This article可能有助于澄清事情。

  6. 请记住,makeExecutableSchema在您不再嘲笑所有内容后,会单独使用typeDef和resolvers。