In my current schema, I have some about 15-ish types like this:
type CoffeShop {
name: String!
createdBy: User!
...
}
all of them having a createdBy-reference to the user. The complete schema is then generated, with queries, mutations and all. However, we don't want users to be able to specify createdBy when they are doing mutaitons, as we get that information from authentication-information.
We have tried to remove overy instance of createdBy from the generated input-types, but this is fast turning into a chore.
After looking at transformSchema, we see that it could possibly be used for this. However, I find it a bit difficult to know exactly how I should transform. I could not find this information in the documentation. What fields in the schema would be input?
Basically, I'd like to remove every field of type input that has the name createdBy.
+1, Tried FilterByTypes and FilterRootFields couldn't make it work.
As a temporary workaround, I created a rough schema-generator for this. It is very basic, but we have used it successfully for about a month now, doing most of what we need in a very dynamic way. It is of course not an ideal solution. https://github.com/runar-indico/graphql-schema-transformer
Moving to v5.1, reopening to move any relevant discussion here.
This is not as simple as changing the input objects, because you also have to provide a mechanism for setting default values for non optional input values
@yaacovCR Should I open a separate issue to deal with query and mutation arguments?
I think it would all be part of same transformer, so can be tracked together
See #1551 which allows filtering and renaming input fields but does not yet address fully the issue of modifying the arguments.
Please comment there on desired approach.
Try out the new FilterInputObjectFields transform from #1551:
npx match-version @graphql-tools 6.0.8-alpha-4aeb995.0
Usage as follows:
describe('transform input object fields', () => {
test('filtering works', async () => {
const schema = makeExecutableSchema({
typeDefs: `
input InputObject {
field1: String
field2: String
}
type OutputObject {
field1: String
field2: String
}
type Query {
test(argument: InputObject): OutputObject
}
`,
resolvers: {
Query: {
test: (_root, args) => {
return args.argument;
}
}
}
});
const transformedSchema = wrapSchema(schema, [
new FilterInputObjectFields(
(typeName, fieldName) => (typeName !== 'InputObject' || fieldName !== 'field2'),
// Below is where you can supply the targetSchema with a value for the
// stripped input field -- if you want
// delegationContext gives you access to the overall delegationContext
// i.e. the relevant options from delegateToSchema
// with the graphql context under delegationContext.context, for example
// request gives you access to the request so far, including variables, etc.
(typeName, inputObjectNode, /* delegationContext, request */) => {
if (typeName === 'InputObject') {
return {
...inputObjectNode,
fields: [...inputObjectNode.fields, {
kind: Kind.OBJECT_FIELD,
name: {
kind: Kind.NAME,
value: 'field2',
},
value: astFromValue('field2', GraphQLString),
}],
};
}
}
)
]);
const query = `{
test(argument: {
field1: "field1"
}) {
field1
field2
}
}`;
const result = await graphql(transformedSchema, query);
expect(result.data.test.field1).toBe('field1');
expect(result.data.test.field2).toBe('field2');
});
});
Should be available in latest release, needs docs
Most helpful comment
Try out the new FilterInputObjectFields transform from #1551:
npx match-version @graphql-tools 6.0.8-alpha-4aeb995.0Usage as follows: