Modify GraphQLObjectType fields at runtime

1.1k Views Asked by At

Assume I have the following code as graphql schema. A userType including id and name for users, and there's two kind of queries: allUsers: [userType] and user(id: Int!): userType.

let db = [{
  id: 1,
  name: 'Amir'
}, {
  id: 2,
  name: 'John'
}];

const userType = new GraphQLObjectType({
  name: 'User',
  fields: {
    id: { type: GraphQLInt },
    name: { type: GraphQLString }
  }
});


const queryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    allUsers: {
      type: new GraphQLList(userType),
      resolve: () => db
    },
    user: {
      type: userType,
      args: {
        id: { type: new GraphQLNonNull(GraphQLInt) }
      },
      resolve: (_, { id }) => db.find(user => user.id == id);
    }
  }
})

let schema = new GraphQLSchema({ query: queryType });

I need to modify this structure at boot time. I mean before actually executing the last line.

To add more kind of queries, I deferred the schema creation (new GraphQLSchema(...)) to the end, after all the modifications are done. So I can add more fields to the query itself or perhaps modify existing ones.

But how can I modify the types that are already defined? Basically, I need to add other fields to userType, like permissions, which itself is a GraphQLObjectType and has its own resolve function.

Something like this:

let queryFields = {};

const userType = new GraphQLObjectType({
  name: 'User',
  fields: {
    id: { type: GraphQLInt },
    name: { type: GraphQLString }
  }
});
queryFields['allUsers'] = {
  type: new GraphQLList(userType),
  // ...
}
queryFields['user'] = {
  type: userType,
  //...
}

/* HERE <---------------------------------------- */
userType.fields.permission = {
  type: GraphQLString,
  resolve: user => getPermissionsFor(user);
}


const queryType = new GraphQLObjectType({
  name: 'Query',
  fields: queryFields
})

var schema = new GraphQLSchema({ query: queryType });

Thanks!

1

There are 1 best solutions below

0
On BEST ANSWER

What I have done at the end is to add another layer between the logic of my app and GraphQL. So I have created another library that holds the information about the schema and the types, and it has an API to modify the existing types in the schema. Once all the modifications are in place, we can extract a GraphQL schema from the library.

That's the whole idea. For implementation detail, I have wrote a post here: Distributed Schema Creation in GraphQL