1
votes

I have trying to create schemas in Mongoose with ObjectId reference and being able to query them via GraphQL using Apollo Server

I have defined a very basic Book and Author ObjectId ref in mongoose like this

const { ObjectId } = mongoose.Schema.Types;
const AuthorSchema = new mongoose.Schema({
  name: String
});

const BookSchema = new mongoose.Schema({
  name: String,
  author: [{ type: ObjectId, ref: 'Author' }]
});

And having a graphql schema like this

  type Author {
    id: ID!
    name: String
  }

  type Book {
    id: ID!
    name: String
    author: Author
  }

  type Query {
    authors: [Author]
    author(id: ID!): Author
    books: [Book]
    book(id: ID!): Book
  }

  input AddAuthorInput {
    name: String!
  }

  input AddBookInput {
    name: String!
    author: ID!
  }

  type Mutation {
    addAuthor(input: AddAuthorInput): Author
    addBook(input: AddBookInput): Book
  }

The mutation section in resolver for addBook and book query is like this

    addBook: async (_, args) => {
      try {
        const {
          input
        } = args;
        return Book.create(input);
      } catch (e) {
        return e.message
      }
    }

      book: async (_, args) => {
        const { id } = args;
        const result = await Book.findById(id).populate('author').exec();

        console.warn('====== Book query result ======');
        console.log(JSON.stringify(result, null, 2));
        console.warn('====== End Book query result ======');

        return result;

When I query with this

query book {
  book(id: "xxxxxxx") {
    id
    name
    author {
      name
    }
  }
}

I get null in author.name while I can see from the console output that the .populate() was able to get correct result from Authors collection.

This repo includes the sample code I have created

1
You saved my day with your question <3Clément CREUSAT

1 Answers

1
votes

Your mongoose schema is set up to return multiple authors per book:

author: [{ type: ObjectId, ref: 'Author' }]

If it should be just the one author, then just do:

author: { type: ObjectId, ref: 'Author' }

You cannot return an array where GraphQL is expecting a single object and vice versa. If you wanted to keep your mongoose schema the same, you'd need to change the type returned by the author field to a List of Authors:

author: [Author]