在 GraphQL 中返回关系数据时遇到问题

Trouble Returning Relational Data in GraphQL

我正在创建一个 Reddit 克隆,我正在先设置后端,但在创建关系数据时遇到了问题。

当我使用这个查询时:

query {
  subreddit(id: 1) {
    name
    posts {
      title
    }
  }
}

我预计:

{
  "data": {
    "subreddit": {
      "name": "javascript"
      "posts": [
        {
          "title": "JS Post"
        }
      ]
    }
  }
}

我得到的:

{
  "data": null,
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Subreddit.posts.",
      "locations": [
        {
          "line": 4,
          "column": 5
        }
      ],
      "path": [
        "subreddit",
        "posts"
      ]
    }
  ]
}

架构如下:

type Query {
  subreddits: [Subreddit!]!
  subreddit(id: ID!): Subreddit!
  posts: [Post!]!
  post(id: ID!): Post!
}

type Mutation {
  createSubreddit(
    name: String!
    description: String!
    contentType: String!
    ageRestriction: Boolean!
  ): Subreddit!
}

type Subreddit {
  id: ID!
  name: String!
  description: String!
  contentType: String!
  ageRestriction: Boolean!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  body: String!
  subredditId: ID!
  # userId: ID!
}

这里是server/index.js:

const { GraphQLServer } = require('graphql-yoga');

let dummySubreddits = [
  {
    name: 'javascript',
    description: 'all things javascript',
    contentType: 'any',
    ageRestriction: false,
    id: 1
  },
  {
    name: 'react',
    description: 'all things react',
    contentType: 'any',
    ageRestriction: false,
    id: 2
  },
  {
    name: 'primsa',
    description: 'all things prisma',
    contentType: 'any',
    ageRestriction: false,
    id: 3
  }
];
let idCountSubreddit = dummySubreddits.length;

let dummyPosts = [
  { title: 'JS Post', body: 'Body of post one', id: 1, subredditId: 1 },
  { title: 'React Post', body: 'Body of post two', id: 2, subredditId: 2 },
  {
    title: 'Prisma Post',
    body: 'Body of post three',
    id: 3,
    subredditId: 3
  }
];
let idCountPost = dummyPosts.length;

const resolvers = {
  Query: {
    subreddits: () => dummySubreddits,
    subreddit: (parent, args) => {
      return dummySubreddits.find(obj => obj.id == args.id);
    },
    posts: () => (parent, args) => {
      return dummyPosts.find(obj => obj.subredditId == parent.id);
    },
    post: (parent, args) => {
      return dummyPosts.find(obj => obj.id == args.id);
    }
  },
  Mutation: {
    createSubreddit: (parent, args) => {
      let subreddit = {
        id: idCountSubreddit++,
        name: args.name,
        description: args.description,
        contentType: args.contentType,
        ageRestriction: args.ageRestriction
      };
      return subreddit;
    }
  }
};

const server = new GraphQLServer({ typeDefs: './schema.graphql', resolvers });
server.start(() => console.log('Server is running on localhost:4000'));

我正在使用 GraphQL 桌面应用程序进行查询,但我没有 grapql-yoga 配置文件。

我哪里错了?我想指出正确的方向,以便我自己弄清楚。这是我第一次单独使用 GraphQL,在 YouTube 上做了一些教程之后,但是他们使用 graphql-express 而我使用 graphql-yoga.

将您为 Queryposts 编写的解析器移动到 Subreddit 以解析那里的帖子字段。如果您的解析器不符合默认解析器实现:

(parent) => parent[fieldName]

就像你的情况

(parent) => parent.posts

你得自己指定。如果您在 Query 上的字段 posts 应该显示您可能想要进行以下实施的所有帖子:

const resolvers = {
  Query: {
    subreddits: () => dummySubreddits,
    subreddit: (parent, args) => {
      return dummySubreddits.find(obj => obj.id == args.id);
    },
    posts: () => dummyPosts,
    post: (parent, args) => {
      return dummyPosts.find(obj => obj.id == args.id);
    }
  },
  Subreddit: {
    posts: () => (parent, args) =>
      dummyPosts.filter(obj => obj.subredditId == parent.id),
  },
  Mutation: {
    createSubreddit: (parent, args) => {
      let subreddit = {
        id: idCountSubreddit++,
        name: args.name,
        description: args.description,
        contentType: args.contentType,
        ageRestriction: args.ageRestriction
      };
      return subreddit;
    }
  }
};

我不得不为 subreddit 添加一个解析器来处理 posts

const resolvers = {
  Query: {
    subreddits: () => dummySubreddits,
    subreddit: (parent, args) => {
      return dummySubreddits.find(obj => obj.id == args.id);
    },
    posts: (parent, args) => {
      return dummyPosts;
    },
    post: (parent, args) => {
      return dummyPosts.find(obj => obj.id == args.id);
    }
  },
  Mutation: {
    createSubreddit: (parent, args) => {
      let subreddit = {
        id: idCountSubreddit++,
        name: args.name,
        description: args.description,
        contentType: args.contentType,
        ageRestriction: args.ageRestriction
      };
      return subreddit;
    }
  },

  // This resolver was needed
  Subreddit: {
    posts: subreddit =>
      dummyPosts.filter(obj => obj.subredditId == subreddit.id)
  }
};