Solving issues with complex GraphQL queries that do not align with the database schema

Short version: How can nested GraphQL queries be resolved when the GraphQL Schema differs from the data stored in a MongoDB database?

In our application, each user in our database has an array of foreign keys referencing other documents, such as "pets," which are stored in a separate collection.

{
  "humans": [
    {
      "id": "1",
      "name": "bob",
      "pets": [
        "jBWMVGjm50l5LGwepDoty1",
        "jBWMVGjm50l5LGwepDoty12"
      ]
    }
  ]
}

We have a GraphQL API in front of this database, and we are working on writing resolvers to handle nested queries. However, the challenge is that our GraphQL schema does not align with the database schema. For example, within the Human type, the pets field expects an array of pet objects:

type Human {
  id: ID!
  name: String!
  pets: [Pet!] # This should be an array of pet objects...
  gender: String!
  hair: String!
  favoriteNum: Int!
  alive: Boolean!
  createdAt: Int!
}

Currently, the resolver for humans retrieves a human by ID from the database and returns that human:

human(parent, { input }, { models }) {
   return models.Human.findOne({ id: input.id });
}

The issue arises because the returned human object from the database does not match the GraphQL schema. The array of "pets" is actually an array of IDs rather than objects. How should we properly resolve this query?

We have attempted to include another database call for the human's pets within the humans resolver. However, this approach leads to unnecessary data retrieval if a query is made only for the human's name...

A similar dilemma would arise if our pets also had foreign keys! What is the best solution to address this issue?

Answer №1

Looks like this is a question related to design principles. In Graphql, it's important to always resolve a graph to ensure that the query caller receives all references to the object. Let's consider the human type here and view it from the perspective of the caller. When the caller encounters the pets field in the human object, they expect to receive this object through a query like:

query(
  human(id) {
    pets {
       stuffOnlyPetshave
    }
  }
)

One way to approach this is by querying the pets directly from your database within the human resolver. This would be the default method to obtain the complete graph.

However, if you aim to reduce the number of database queries for every human query, then consider implementing a conditional pet query on your frontend.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing TypeScript to enhance method proxying

I'm currently in the process of converting my JavaScript project to TypeScript, but I've hit a roadblock with an unresolved TypeScript error (TS2339). Within my code base, I have a class defined like this: export const devtoolsBackgroundScriptCl ...

Tips for eliminating the glowing effect when pressing down on the thumb of the material ui slider

Visit Material-UI documentation for Slider component. Despite setting the disabled flag for the entire slider, the thumb continues to show a halo effect when clicked. ...

Angular menu with nested dropdowns

Is it possible to create a nested select menu similar to the example select screenshot menu below, using my mat-select? When a user selects an item from the REPM mat select, it should display the Master Broker Company menu on the right side. Thanks. #exam ...

Is it possible to send a request to the backend and continuously scan and update the database until a match is found, and then send the response?

I’m currently facing a challenge in developing my own matchmaking system for a two-player multiplayer game. I have a "play" button that, when pressed by the user, should update their schema property in the database to "inQueue: true". After this update, ...

The essence of my design disappears when I generate a canvas object using Fabric.js

After defining top and left attributes for a Canvas Object using a JavaScript function, I encounter an issue when creating a fabric Canvas object. var fabricCanvas = new fabric.Canvas('mycanvas'); Upon creation, my HTML Canvas has its top and ...

What is the cost associated with using the require() function in an Express.js application?

I have a web application built with Express.js that serves one of my domains. The structure of the app.js file is as follows: var express = require('express'); var app = express(); // and so on… To incorporate one of my custom functions in t ...

Exploring the Node Promise Chain: Utilizing Local Functions and Managing Multiple Value Passing in a Code Review

Upon reviewing the code provided, several questions have arisen: #1 I am curious about the best way to make the values returned by the bluebird.all functions accessible in subsequent functions. Is using the this-context a viable option without declaring t ...

The jQuery click function triggers immediately upon the loading of the page

Despite my best efforts to resolve this issue independently and conduct extensive research on Google, I am still unable to identify the root of the problem. It seems that the click function continues to activate upon page load. Kindly elucidate the under ...

Can integers be used as keys in a JavaScript object's storage?

Currently, I am in the process of creating a JSON index file to serve as a database index for a javascript application that is currently under development. The structure of my index will resemble the following: { "_id": "acomplex_indice ...

JS Month Interval Bug Causing Issues with Chart Date

This script retrieves and summarizes download data from MySQL by day, displaying it as a chart. However, there's an issue with the way dates are handled between PHP and JavaScript (Highcharts). While PHP outputs month values from 1 to 12, JavaScript c ...

Issue with using Bootstrap-select in conjunction with HTMX partials

I'm currently experimenting with using Bootstrap-select alongside HTMX partials in my Django project. When a specific element is modified, HTMX returns a partial HTML that includes only a dropdown menu, like this: <select id="myDropdown" ...

How can I show the remaining paragraph text upon clicking a button in a responsive manner using CSS and JavaScript?

I want to add a nice animation effect to the height of my text when a button is clicked. I've managed to achieve this by setting a height: 30px with overflow: hidden initially, and then toggling a class with height: 300px. However, I'm facing an ...

VSCode API alerts user when a rejected promise is left unhandled for more than a second

After working diligently on developing my first vscode extension, I encountered a roadblock when the debugger halted the execution of my extension. As a newcomer to JavaScript, I suspect that I may be overlooking something related to "thenables" that is c ...

Encountered an unforeseen character 'u' in the initial position of the JSON while attempting to create a plugin

I seem to be encountering some issues with my code. Whenever I attempt to run the script in the developer kit, an error is thrown: unexpected token u in JSON at position 0... funciones.js $(document).ready(function (){ $("#btn1").click(funct ...

How come AJAX is not successfully processing the image file?

It's puzzling that the image file in the form is being processed without any issues when Ajax is not used, but encounters a problem with the Ajax script provided below. I'm struggling to understand why this discrepancy exists... Please note: Th ...

Tips for displaying information from MongoDB using ObjectID

I am currently working on a "back end" application written in MongoDb (the database includes _id: with ObjectId("13f6ea...002")). I am using a meteor app to display the information. Initially, everything was working fine as I was able to display a list of ...

How can you check if an ID exists within an array of IDs using MongoDB?

I have a model with a property _idUserReadArr // array of users who have read an article This array is expected to be very large. My goal is for the API to provide a boolean value isRead This value should be true if _idUserReadArr contains a specific ...

What are the steps to creating a duplicate of JotForm?

After exploring JotForm, I discovered it is an extremely interactive form builder utilizing the Prototype JS library. I am curious to know which JS framework or library would be a solid foundation for creating a similar form builder - JQuery, Prototype, ...

Is it possible to modify a single entry in a series of records?

I have a list of data entries, such as addresses, and I am currently displaying them using the following combination of html5 and knockout code. <section id="lists" data-bind="foreach: addresses, visible: addresses().length > 0"> <article& ...

What is the best way to eliminate the # symbol from a URL within a Vue.js application when utilizing a CDN

When constructing a vue.js application using CLI and vue-router, you can include mode: 'history' in the router to remove the hash from the URL. However, is there a way to eliminate the # from the URL when using Vue through a CDN? For instance, in ...