Проблемы с возвратом реляционных данных в GraphQL - PullRequest
0 голосов
/ 24 мая 2018

Я создаю клон 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.

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Мне пришлось добавить распознаватель для 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)
  }
};
0 голосов
/ 24 мая 2018

Переместите преобразователь, который вы написали для Query posts, в Subreddit, чтобы разрешить поле сообщений там.Если ваш распознаватель не соответствует реализации распознавателя по умолчанию:

(parent) => parent[fieldName]

Как и в вашем случае

(parent) => parent.posts

Вы должны указать это самостоятельно.Если в вашем поле posts на Query должны отображаться все сообщения, которые вы можете использовать для следующих реализаций:

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;
    }
  }
};
...