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

Support lists in external reference resolvers #8001

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

luke-pp
Copy link

@luke-pp luke-pp commented Feb 6, 2025

Add support for the Apollo [External] attribute/directive on list types.

  • Currently the ArgumentParser class does not support list types, meaning the reference resolver always receives null for the external list type even when a list is provided to it (see Support lists in Apollo Federation reference resolvers #7991 for details)
  • This PR adds a test to the existing suite for the @external support, and an implementation for the ArgumentParser that lets it parse lists.
  • The implementation is based on the existing implementation for the InputParser, although the function signature is a bit different
  • There are a couple of edge cases that still need implementation, I'll need a bit of guidance to make sure they work as intended

Closes #7991

@CLAassistant
Copy link

CLAassistant commented Feb 6, 2025

CLA assistant check
All committers have signed the CLA.

var succeeded = (bool) innerTryGetValueMethod.Invoke(null, parameters)!;
if (!succeeded)
{
throw new NotImplementedException();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% clear on the signature for the function - if we fail to parse any of the list elements, should we short-circuit and just return false? Do we need to make any changes to value?

{
throw new NotImplementedException();
}
var innerValue = parameters[4]!;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this way of doing things, but I'm not familiar enough with dotnet reflection to know a better way of doing it. From what I can tell:

  1. This method is generic over T, which should be something like List<E>, but we need to recurse by calling TryGetValue<E> on each list element.
  2. This forces us to use the MakeGenericMethod stuff around lines 74-82.
  3. This means we need to call the method using Invoke rather than being able to pass in parameters normally. Invoke takes in an array of object? as its parameters
  4. This gets pretty annoying when dealing with out var parameters - you have to pass in null and then grab out the specific parameter by index here after calling the method.

To me this feels quite fragile, as if the arguments for this method change, this will break. This should be caught by the test added in this PR, but I'm open to other ways of implementing this that'd be more elegant!

}
else
{
throw new NotImplementedException();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure how to handle nested lists in this case. Does it actually matter? I think the logic just works the same way. I'll try adding another test case for this to confirm it works.

public string Id { get; }

[External]
public List<double> ListField { get; }
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this locally by swapping out various types of lists, but I'm happy to add in a more comprehensive set of tests depending on what you'd prefer eg:

  • Just the one test, but adding in many external list fields with differing inner types
  • Tests for a few key types (eg: nested lists/lists of objects)
  • I could try and find a way to parameterize the test for the list's inner type but I think that'd be overcomplicating things

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

Successfully merging this pull request may close these issues.

Support lists in Apollo Federation reference resolvers
2 participants