Search code examples
javascriptgraphqlaxiosprismaprisma-graphql

How to do multiple nested query (GET request) with GraphQL Yoga?


How can I do multiple nested query using GraphQL Yoga?

This is my data

{
  "user": [{
      "id": 1,
      "name": "Thomas",
      "comment_id": [1, 2, 3]
    },
    {
      "id": 2,
      "name": "Riza",
      "comment_id": [4, 5, 6]
    }
  ],
  "comment": [{
      "id": 1,
      "body": "comment 1"
    },
    {
      "id": 2,
      "body": "comment 2"
    },
    {
      "id": 3,
      "body": "comment 3"
    }
  ]
}

The scenario is that I want to query a particular user with all its comments, but the user only stores the comment ids.

This is my code

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

const typeDefs = `
  type Query {
    user(id: Int!): User
    comment(id: Int!): Comment
  }

  type User {
    id: Int
    name: String
    comment: [Comment]
  }

  type Comment {
    id: Int
    body: String
  }
`;

const resolvers = {
  Query: {
    user(parent, args) {
      return axios
        .get(`http://localhost:3000/user/${args.id}`)
        .then(res => res.data)
        .catch(err => console.log(err));
    },
    comment(parent, args) {
      return axios
        .get(`http://localhost:3000/comment/${args.id}`)
        .then(res => res.data)
        .catch(err => console.log(err));
    },
  },
  User: {
    comment: parent =>
      axios
        .get(`http://localhost:3000/comment/${parent.comment_id}`)
        .then(res => res.data)
        .catch(err => console.log(err)),
  },
};

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

Desired Query

{
  user(id: 1) {
    id
    name
    comment {
      id
      body
    }
  }
}

But it returns not found, because the endpoint that the axios hit is http://localhost:3000/comment/1,2,3'

How can i make it return all user's comments? Thanks guys!


Solution

  • Assuming that comments API /comment/:id accepts only single id, you would need to make one API call per comment ID (unless there is an API which takes multiple ID's and return their data) and then return response from comment field resolver of User type.

    This is how resolver for comment field would look like in that case:

    User: {
        comment: parent => {
            let results = await Promise.all(parent.comment_id.map((id) => axios.get(`http://localhost:3000/comment/${id}`))) 
            return results.map((result) => result.data)
         }
      }