0

我以编程方式创建了一个模拟来测试我的查询,但它只返回一个空值我做错了什么。我正在使用休闲库为我的模拟生成值

这是我的文件:

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]

模拟.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\"."
    }
  ]
}

我究竟做错了什么

4

1 回答 1

3

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

  1. 确保您正确实施模拟。我认为makeExecutableSchema曾经一度接受模拟选项,但现在您必须addMockFunctionsToSchema结合使用它来实现模拟。我会阅读Apollo 的模拟指南,了解如何做到这一点的详细步骤。

  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. 如果您使用上述方法,您最终需要将查询更改为 fetch [NovelCrawler]等待!在使事情变得更复杂和更难调试之前,我建议只模拟Chapter并添加一个查询以获得[Chapters] first。一旦你完成了这项工作,你就会知道你已经掌握了基本功能,并且可以开始模拟和查询更复杂的数据结构。

  5. 如果您确实需要接口,请确保您了解它们提供的功能以及如何正确实现它们。这篇文章可能有助于澄清事情。

  6. 请记住makeExecutableSchema,一旦您不再模拟所有内容,就将 typeDefs 和解析器分开。

于 2017-07-06T06:06:59.277 回答