-
Notifications
You must be signed in to change notification settings - Fork 60
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
[RFC] Scoped context #159
base: master
Are you sure you want to change the base?
[RFC] Scoped context #159
Conversation
Thanks for the PR and for writing this up, @dwwoelfel! I think we can address a number of use cases with option 2 of the "other ideas" you mention: a new abstract type, e.g. It would be great if we can make an exhaustive list of possible return values from a resolve function. Here's my first take on it:
Does that make sense? Have I missed any cases? |
I agree with @andreas here. Adding a new type of field for each new use case creates the unfortunate explosion in combinations as you now have to add an @andreas are you suggesting that every resolver now returns that abstract type? I might be missing something, but it doesn't seem that it would preserve backwards compatibility (maybe there's a way I'm not seeing). I think that the solution to this particular use case should also take into account that a GraphQL response can return both data and errors. We could perhaps do ourselves a favor here by providing a solution that also encompasses that? |
I think the only case where the resolver function could return both an error and a result is when the resolver is returning a list (e.g. For lists, the resolver might want a special One of the more annoying things we deal with manually right now is converting |
Yes, I would preserve backwards compatibility by leaving
I haven't researched this in depth, but there does not appear to be consensus about whether a resolver should be allowed to return a success value and include errors. Absinthe (Elixir) apparently disallows it (discussion here), while other implementations appear to allow it (e.g. About errors and lists with nullable contents, some use cases are covered (e.g. list of nullable object type as shown in this test case). It's true that a list of nullable scalars cannot easily be expressed though, but that also seems like weird use case. Can you elaborate on this, @dwwoelfel? |
I definitely would like to be able to return both a success and an error value - probably for scalar fields as well, but at least for lists fields (where we were able to retrieve 5/10 items, and 5/10 caused errors - I want to report on the errors, but return as many of the positive items as possible) |
We don't have a use-case for returning a list of nullable scalars. It's just a simplification of what we want to do, which is return a list of objects, where some of the objects are nulls. The test case you linked to is one way to solve the problem, but it means that you have to push the logic of when to show an error to the object's resolver instead of the resolver generating the list. I'm pretty sure that graphql-js resolvers let you return a list like
I don't think returning an error and success for a scalar value would comply with the spec. For example, if you're going to return an error for a nullable field, the field should be null. Having something like |
@dwwoelfel Thanks for following up. I've thought more about this since -- here's an attempt to summarise the situation right now: The current design is that the type parameter I have two different ideas to address this:
Lastly, solving the problem of returning errors for individual list elements does not solve the problem originally posed in this PR: changing the context value. It still seems like adding a type |
We're working on a feature for OneGraph that allows users to query data across multiple accounts for the same provider in a single GraphQL query. For example, with our Gmail integration, you'd be able to query for both your work and your personal email in the same query.
We'll be using an argument to allow the user to specify which account to query. It would look something like:
We'd like to use scoped context to make sure the subqueries use the correct account.
Background
Lacinia, the Clojure GraphQL library, implements scoped context: https://lacinia.readthedocs.io/en/latest/resolve/context.html
There's a short discussion in the graphql-js repo here: graphql/graphql-js#354
Implementation
This adds a new
io_field_with_set_context
field that behaves like anio_field
, but passes a function to the resolve function that allows it to set the context for the child fields.In usage, it looks something like:
I don't think this is the best way to implement the feature, but I ran into troubles getting the types to work with other approaches. I'd love to get some feedback on how you'd think about implementing other approaches.
Other ideas for implementation:
io_field_with_set_context
to a tuple or record with context and the normal result. This is what I initially attempted and where I got stuck.io_field_with_set_context
above would be a normal io_field withResolve.with_context((), {ctx with gmailAccountId = (Some (accountId))})
.