-
-
Notifications
You must be signed in to change notification settings - Fork 818
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
Add fragments in schema directives #984
Comments
Yes, it would be perfect if for example I could do something like the following: class TestDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field, details) {
field.fragment = `fragment Fragment on ${details.objectType.name} { id }`;
field.resolve = (parent, args, context, info) => {
// Do anything you want with parent.id
// This would be VERY useful for authorization/permissions
return 'It works';
};
}
} |
+1 I need exactly this feature please. Consider the following use case: Let's say I have a model like this: type User {
email: String!
chatRooms: [ChatRoom!]!
}
type ChatRoom {
id: ID!
chatMessage: [Message!]!
}
type Message {
id: ID!
chatRoom: ChatRoom!
content: String!
}
type Mutation {
deleteMessage(id: ID!): ChatMessage! @isChatRoomMember
}
Now the The only way I see to implement such a directive is if fragments could be resolved for directives then I could simply make sure the chatRoom field is always resolved and available in the directive. Of course it is trivial to implement such a check in this case, but imagine a far more complex model where you don't want to implement that check in each resolver and you want to make the permissions visible in your model definition. |
Anything new about this? I need it! (without calling root resolvers previously) |
I also still would love to have this. I have implemented a rather sophisticated and useful permissions model with schema directives, but without fragments I am requesting extra information that could have been returned in the selection set in the resolver that I overwrite. This does not scale! For each record I check permissions on, I have to do an extra request to the database, which is fine when requesting a few records, but with hundreds or thousands this grinds my server to a halt. |
A schema directive cannot modify the query -- it can only modify the schema. Query modification can be done by the wrapping server (express-graphql, apollo-server), within the execution algorithm itself (graphql-js) or by creating a wrapping schema with a transform (graphql-tools). Based on above, it seems what you want is a way to specify -- together -- what transforms you want the wrapping schema to apply and what schema directives you want the subschema to use. That seems definitely doable, but probably not using the existing schema directive patterns. |
With the new functionality in PR #1463 (closing #1234), you can create a schemaTransform function that does two things: (1) modifies the resolver within a given schema by calling mapSchema (2) wraps the given schema with wrapSchema and a transform object that defines a { transformRequest } property adding the fields you need (you could also check out the perhaps strangely named existing AddReplacementSelectionSet, AddReplacementFragment or ReplaceFieldWithFragment transforms to see if they accomplish what you need in terms of adding fields -- I don't believe they actually replace the fields in question, that language is just taken from stitching where the field is not expected to exist on the subschema, but I think most if not all of them just add fields). An example of this would be helpful, but hopefully the new docs in #1463 landing soon should get you started with what's possible. |
Note that I listed other options available to you to add fields that are probably more performant. By wrapping the schema, you will get two rounds of graphql-js execution. It would be better to have the server add the fields or if graphql-js had middleware that could easily do it. |
The new AddSelectionSets is a maybe better named transform that takes as arguments a source schema, a map of which selection sets to add based on the presence of types and/or enclosed fields, and an "initial type" for the selection set traversal which -- when dealing with a proxied request -- should usually be the expected return type of the proxying root field. |
Closing this stale issue. Feel free to reopen if there is anything we can be further help with... |
Right now there doesn't seem to be a way to request additional fields other than what is in the user-defined selection set in a schema directive. It would be very useful to request additional fields that the user did not request, within a schema directive. This would open up more possibilities for directive permissions. Essentially, from within a schema directive implementation, I would like to not only be able to define a custom resolver, but a custom fragment to be applied to the parent when that resolver is invoked at runtime.
The text was updated successfully, but these errors were encountered: