Home > Back-end >  How to represent a map or object with key-value pairs in GraphQL?
How to represent a map or object with key-value pairs in GraphQL?

Time:12-07

How can I query for the following object?

{
     result: {
          '1': {
          ^^^ these are dynamic keys, never constant
               id: 'id1',
          },
          '20': {
               id: 'id2',
          },
          '300': {
               id: 'id3',
          },
     }
}

I know that I can define the result object fairly simply, if it wasn't a key-value pair object.

const ResultQueryType = new GraphQLObjectType({
     name: 'ResultQueryType',
     fields: () => ({
          id: { type: GraphQLString }
     })
})

But this is clearly not what I need. I haven't encountered such a scenario with GraphQL yet, what can I do here?

CodePudding user response:

You can try the dynamic key as suggested here. https://graphql.org/graphql-js/type/#graphqlobjecttype

const ResultQueryType = new GraphQLObjectType({
  name: "ResultQueryType",
  fields: () => ({
    [fieldName: string]: { type: GraphQLString },
  }),
});

CodePudding user response:

You can only query fields that have been explicitly defined in the schema.

Spec: The target field of a field selection must be defined on the scoped type of the selection set.

Docs Every GraphQL service defines a set of types which completely describe the set of possible data you can query on that service. Then, when queries come in, they are validated and executed against that schema.

In other words, you can't have a Results map type (and therefore can't query it) if its fields are not known to the schema definition. There are a couple of workarounds:

  1. Use JSON. Many implementations let you define custom scalars as JSON or have a JSON type that is a String alias. You keep the map structure but lose type awareness. It's left to the client to parse the result.
  2. Refactor your map to an array. If you can merge the top-level key into each record, you can return an [Item] array. You have to abandon the map, but you keep full GraphQL type-awareness.
  • Related