Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Add addField method for object type #1774

Closed
pd4d10 opened this issue Mar 7, 2019 · 4 comments
Closed

[Proposal] Add addField method for object type #1774

pd4d10 opened this issue Mar 7, 2019 · 4 comments
Labels

Comments

@pd4d10
Copy link

pd4d10 commented Mar 7, 2019

Currently there seems no way to manipulate existing object types. It would be handy to have addField method as follows:

const objType = new GraphQLObjectType({
  name: 'SomeObject',
  fields: {},
});

objType.addField('add', { name: 'add', type: GraphQLInt });

objType.getFields()
// {
//   add: { name: 'add', type: GraphQLInt },
// );
@IvanGoncharov
Copy link
Member

IvanGoncharov commented Mar 7, 2019

@pd4d10 All GraphQL*Type are immutable by design, meaning you can't change them after creation.
So we can't add 'addFieldor any other function that mutate instance ofGraphQLObjectType`.

Can you please share your use case?
Why do you need addField function?

@pd4d10
Copy link
Author

pd4d10 commented Mar 7, 2019

Thanks for the quick reply.

The current use case is, GraphQL types are generated at runtime from some other IDL, like Thrift or Protobuf. Sometimes it is not exactly we want. So I'm thinking a way to do some tweak based on it.

It is also inspired by graphql-go:
https://github.com/graphql-go/graphql/blob/a5c80ac140e28c006805b9fdc77bc54160ccb3f8/definition.go#L402

@pd4d10
Copy link
Author

pd4d10 commented Mar 7, 2019

Since types are immutable by design, I guess the best practice is to manipulate schema.graphql and then generate types from schema again?

@IvanGoncharov
Copy link
Member

@pd4d10 We are working on the new transformSchema function specifically designed for this use case. As one of the steps toward this goal, we added toConfig method to every GraphQL*Type class.
So you can do:

const config = objType.toConfig();
const modifiedType = new GraphQLObjectType({
  ...config,
  fields: {
    ...config.fields,
    add: { type: GraphQLInt },
  },
});

But please note that other types can reference old type object so you need to also update them to point to modified type. Also, note that GraphQLSchema is also designed to be immutable. Here is a complete example of how to properly use toConfig:
https://github.com/graphql/graphql-js/blob/master/src/utilities/lexicographicSortSchema.js

It's pretty low-level API and it's hard to use it directly that's why we working on adding more high-level transformSchema API.

Meanwhile, you can use external packages for schema manipulation, e.g. graphql-compose.

I'm closing this issue since it will be fixed by transformSchema that is tracked under #1199

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants