-
Notifications
You must be signed in to change notification settings - Fork 257
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
fix(federation): differentiate field and input value names #280
fix(federation): differentiate field and input value names #280
Conversation
@patrick91: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/ |
Interesting bug, and good catch! Thanks for opening this - is this something you're interested in fixing as well? |
@trevor-scheer I can give a try on the weekend! Do you have any pointer? |
@patrick91 Awesome! I see the issue - let me know if you'd like me to go into any more detail. I don't want to steal the solution from you if you're interested in the solve, but happy to provide as much assistance as you're interested in. This object seems to be doing a bit more work than it should within the validator: federation/federation-js/src/composition/validate/sdl/uniqueFieldDefinitionNames.ts Lines 68 to 70 in e8fae64
|
@trevor-scheer I think I'm having some troubles understanding the code. I think the issue is in I wonder why a visitor has been used for this function, aren't type definitions basically flat? If I understood correctly with the current code what happens is that both fields names and argument names are put inside |
@patrick91 you're on the right track! You're right that As far as the function goes, I can imagine two solutions:
function fieldVisitorFactory(diff) {
return function visitor(node) {
//...previous fieldVisitor logic captured here
}
} Then where we call visit(document, {
FieldDefinition: fieldVisitorFactory(fieldsDiff),
InputValueDefinition: fieldVisitorFactory(inputValuesDiff),
// ...
});
Is that helpful? Let me know if you have any more questions 🙂 P.S. I lean toward 2 myself. It's less clever. I wrote this code and find it a bit of a stretch to combine this logic. |
@trevor-scheer took me a while to get back to you, but I think I managed to make it work, I went for suggestion 2, let me know how it looks. The tests are passing on my machine 😊 |
3898e9f
to
bc9f13a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @patrick91! This is looking great, I have one more comment for you to address and this should be ready to ship.
Please add a changelog entry to the federation-js/CHANGELOG.md
file as well.
db3a46b
to
6cade24
Compare
|
||
const fieldsDiff = Object.entries(fields); | ||
const fieldsDiff = Object.entries(fields).concat(Object.entries(inputValues)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this make sense @trevor-scheer ?
I think we might need to update checkFieldUniquenessExcludingValueTypes
as well :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might work but I'm not sure the error reporting will be very accurate if we group these diffs into the fieldsDiff
. Notice down below (L97) when we iterate over fieldsDiff
, we might push error messages that relate to a field, but the error code and message don't really hint at input values. It seems appropriate to introduce another error code, like VALUE_TYPE_INPUT_VALUE_MISMATCH
and have some similar iteration over the inputValuesDiff
which contributes to the typesHaveSameShape
evaluation. Does that make sense? It's similar to what you're already doing, but it does split out the iteration over inputValues
so we can provide a more targeted error message.
Feel free to draw inspiration from the format and wording of existing error messages, or I'd be happy to provide guidance there. There's also some documentation around our error codes which would need a matching update:
federation/docs/source/errors.md
Line 89 in 8b5ebc6
| `VALUE_TYPE_KIND_MISMATCH` | An implementing service defines a type with the same name and fields as a type in another service, but there is a declaration mismatch. For example, `type MyType` is invalid if another service defines `interface MyType`. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're right that an update to checkFieldUniquenessExcludingValueTypes makes sense as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really happy with the code duplication, I was thinking of moving the check to a function, but we'd need to change a bit how we report the error, so might not be worth it :)
c7a77e5
to
f3656ee
Compare
if (types.length === 2) { | ||
possibleErrors.push( | ||
errorWithCode( | ||
'VALUE_TYPE_INPUT_VALUE_MISMATCH', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get a test case that exercises this code path and demonstrates what will trigger this error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done! I wish we could access the field name to improve the error message, but alas I wasn't able to :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I think we can find a way to pass that info down through the diff but I'm really happy with where we've landed here. This feels ready to land to me and I don't want to block getting this released. If you don't mind opening an issue that references this PR comment that would be wonderful!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done :)
federation-js/src/composition/validate/sdl/uniqueTypeNamesWithFields.ts
Outdated
Show resolved
Hide resolved
f3656ee
to
f0841d4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has come together really nicely, @patrick91. Huge thank you for your initial efforts and timely updates! 🎉
Did you have any lingering concerns with checkFieldUniquenessExcludingValueTypes
? I don't think we addressed that yet. After quickly refamiliarizing myself and reading the comments, it seems right to leave it as is, but I'm open to hearing otherwise.
}); | ||
}); | ||
|
||
it('object type definitions field different order', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this test just asserting that order is irrelevant for fields when determining value types? Just want to make sure I understand this test isn't related to your changes (but let's keep it!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup! it was failing before we did the change to fieldDiff, oddly :)
I've updated the test to have a better name (and made the schema nicer too) :)
if (types.length === 2) { | ||
possibleErrors.push( | ||
errorWithCode( | ||
'VALUE_TYPE_INPUT_VALUE_MISMATCH', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I think we can find a way to pass that info down through the diff but I'm really happy with where we've landed here. This feels ready to land to me and I don't want to block getting this released. If you don't mind opening an issue that references this PR comment that would be wonderful!
@trevor-scheer thank you for the patience! Regarding If this is ready to merge, do you want me to squash the commits? |
@patrick91 That would be great! |
da1cad3
to
c9356f4
Compare
Thanks again @patrick91! I'll aim to get a patch release out for this tomorrow. |
This is released via ab39394!
|
This only contains the test at the moment :)
I found a bug where I had at type like this:
in two services, and apollo was still complaining about the types being different.
Turns out that the diff is comparing the field
identifier
with the argumentidentifier
,and they have different types.
So, I've added a test for that. I suspect we might have a similar issue with different fields
having the same argument but with different type. I might add a test for that later :)
EDIT: not sure why the tests didn't fail here
Ah, the tests were not running: #281