-
Notifications
You must be signed in to change notification settings - Fork 335
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
Source level resolver compositions are not applied (transform-resolvers-composition) #1891
Comments
I think I just found the reason for the issue we were seeing, as outlined here:
A bit further down it is outline that compositions do not support wrap mode: Based on the above, are we correct in the assumption that there is currently no way to use composition on a graphql data source level? Our goal: |
I don't have experience with resolvers composition transform, but I believe the fact that it doesn't support wrap mode is most likely the issue. Out of interest, I wonder why you have closed the issue, if you found an alternative solution it might be worth sharing with future readers. I think this is an interesting case, it might actually make sense to introduce "wrap" mode to resolvers composition to make it easy to have this transform on GraphQL sources as well. |
@santino Thank you for the link I will research this with my team. I closed the issue as I realized this wasn't a bug, but was working as designed and documented. That said I reopened since you mentioned an interest in potentially supporting this use case. In our opinion it would be very useful to be able to apply compositions on any type of source. The larger use case is the following:
In combination this allows us to integrate external apis 5-10x faster than previously already. With reduction in potential bugs as well as an ability to adapt to changes in the providers api in a much more timely fashion. Some more details can be found in these previous issues and PRs: Additional notes:
|
@santino If the goal is to apply all kind of transforms on handler / source level (incl. graphql data soruces) there I see 2 options:
The advantage of solution 2 are:
|
Thanks for your comments @ntziolis I personally believe we should stick with "wrap" mode when it comes to handling GraphQL sources and I found applying transforms at the source level preferable, with the benefit of delivering polished sources ready for the stitching process. I will review the conversation during the week (right now I'm on a bank holiday). Surely you will get more updates here :) |
Also not a contributor to I can comment on why we don't use Let's use the term Now, in terms of the schema layer -- given an arbitrary schema, we can't quite know whether this is even possible. Let's limit our discussion for a second to a single transform -- renaming a non-root field. Resolver for a given field are quite diverse. Let's a couple of scenarios: (A) A custom resolver may having nothing to do with its field name. In this case, the schema can be safely altered without any worry about modifying the resover. (B) The default resolver does depend on its field name -- that's how it resolves itself, based on the entry under that field name within the parent source. This resolver must be replaced with a resolver that does the lookup based on the original field name. (C) An arbitary resolver may perversely check its field name, and, if not equal to the original field name, always return undefined. This resolver could not be wrapped or altered in any way. What if we limit our discussion of transforms to a certain class of schemas, however? Specifically, schemas that have resolvers in which the source already contains the entire result, because, for example, the root resolver performed a look ahead of the required fieldNodes and queried a database, REST API or external GraphQL endpoint, or what have you? The root field resolvers for these schemas do not depend on the field name (type A) and the non-root field resolvers can be modified to refer to the original field name (B) or may depend on the alias anyway (type A). This is essentially my understanding of "bare" transforms, in which we bake the transformation into the individual field resolvers, and I will call that resolver based transforms from now on. Another option is to traverse the result returned by our database, REST API, or external GraphQL endpoint, and modify it prior to it being returned to GraphQL execution. I will call that ROOT resolver based transforms from now on. This is what some of the Two reasons:
Resolver based transforms are more efficient than root resolver based transforms because the latter hide another layer of result traversal. The latter is basically equivalent to the execution layer transform discussed above, which adds another round of result traversal, it just does it within the root resolver rather than after execution. Now, you may have some GraphQLSchema (de novo, delegating to a database, REST API etc) and wish to transform it, and you may be aware of the many transforms in the I'm not sure if the above is helpful to anyone else, but it was helpful to me! I think there possible ways forward we can work within the [Note parenthetically, that field renaming itself doesn't actually traverse the result at all -- we use alias tricks to rename the fields.] |
@yaacovCR Thank you for these insights. Haven yet fully digested all the information will have another look tmr. bright and early. @santino Before I saw your reply I already went ahead and did a quick and dirty version of what I was trying to convey before. Key part piece is that handlers have a new Have a look here: Please note:
Again this was just a quick shoot in the dark. Me and my team are happy to invest significant time to any solution that gets us to be able to apply all transforms on all levels. |
Didn't manage to discuss this with the Mesh team yet, but I am going ahead and just taking a look at your codesandbox. |
@santino Just to ensure there is no misunderstanding. The codesandbox uses the currently released graphql-mesh libs. In order to tests the changed code above I downloaded the codesandbox and used npm link to use the changed graphql-mesh libs to run it. Please let me know if I can aide this effort in any way, as mentioned before me and my team are willing to contribute significant time to this project moving forward. |
Yes, that was clear 🙂 I have now raised #1928 as a proper solution to this issue. |
@santino Looking forward to hearing what they think. With that in wrap being the default, but bare being the more performant option, it would be nice to:
This would keep the amount of configuration to a minimum in regards to having to specify modes. As well as reduce configuration mistakes by users. Should I open another issue for this as feature request? |
I like the idea, potentially we could just add a new property to the root of mesh config that sets the default transform mode. It sounds good, but obviously, right now only two plugins support both modes, and with resolvers-composition it would be three. Yes, feel free to open another issue. |
Sry of not clear the above only applies when all transforms actually support both modes. Will open another issue to cover both:
|
Hey @ntziolis , Can you confirm the latest releases solved the issue you reported? |
@santino I can confirm that this now works as expected (I used the code sandbox with updated deps to verify). |
Resolver compositions on source level are ignored, at least for a graphql source.
To Reproduce
Steps to reproduce the behavior:
----- GLOBAL composer executed ----
----- SOURCE composer executed ----
respectively----- GLOBAL composer executed ----
entry is logged into the console windowExpected behavior
Both composers should be executed. The expectation would be that
Environment:
@graphql-mesh/transform-resolvers-composition
:Additional context
While debugging we found that while the
resolvers[typeName][fieldName]
key does exist, the data returned doesn't match any of the conditions in the following code block, which prevents matches to be found:https://github.com/ardatan/graphql-tools/blob/master/packages/resolvers-composition/src/resolvers-composition.ts#L57
The text was updated successfully, but these errors were encountered: