GraphQL Express: Queries on child items.

Full disclosure this blog is me learning in public. Maybe this is obvious to you, maybe there is a better way to do this, if so let me know. In the end it caught me out so I thought I'd write down what my solution ended up being.

The problem: In the GraphQL documentation the servers are always shown returning simple hello world style results. I wanted to be able to find all the items associated with a user ID and then all items that match certain criteria within that set. The project that I have been using to learn GraphQL is an implementation of the Tech Radar idea that was popularised by ThoughtWorks. In this the client can select a radar and potentially a subset of the items on the radar, say they only want to display a single section.

In the GraphQL Express examples it shows how to grab top level items, filtering these is easy. You can grab all the data from your data source and pass it through a filter function and return it. Simple. It looks something like this:

1
2
3
4
5
6
7
import data from "./data";
const radarQuery = {
  radars: id => {
    const radars = id ? data.filter(x => x.id === id) : data;
    return radars;
  }
}

The confusing part came with how to add the filtering function for child elements. What GraphQL express expects is that the query returns an object with values where they're set. In this case the radar's id and name fields would be an example but functions where the values are going to be the subject of further filtering.  The answer I've gone with is to map the selector function onto each of the objects returned. This way GraphQL Express knows to filter into these lists as well.
The code ends up looking something like this:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import data from "./data";
const radarQuery = {
  radars: id => {
    const radars = id ? data.filter(x => x.id === id) : data;
    return radars.map(radar => ({
      ...radar,
      items: ({ ring, section }) =>
        radar.items
          .filter(x => (ring ? x.ring.id === ring : true))
          .filter(x => (section ? x.section.id === section : true))
    }));
  }
};


Comments

Popular posts from this blog

Solving `Empty reply from server` in DotNet Core

Testing functions that use local storage with Jest

Building a verify JWT function in TypeScript