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

State that additional properties are ignored #284

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Shane32
Copy link
Contributor

@Shane32 Shane32 commented Jan 26, 2024

Servers don't need to validate this, and in fact they should not since a client from a future spec version may send additional keys, which legacy servers should just ignore.

I think we should add this to the spec. The main graphql spec did not state this explicitly for reserved names (those starting with __), and now any current GraphQL UI applications built on Apollo's graphql library crash if they see additional reserved names in the introspection result. (I consider this a bug but 🤷‍♂️ ). They should be built to ignore additional features added to the spec, and the spec should state this.

We could add something like this:

Servers receiving a request with additional properties MUST ignore the additional properties when processing the request.

Originally posted by @Shane32 in #278 (comment)

Copy link
Member

@enisdenjo enisdenjo left a comment

Choose a reason for hiding this comment

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

I think these two are counter-intuitive:

[...] if implementors need
to add additional information to a request they MUST do so via other means,

[...] Servers receiving a request with additional properties MUST ignore the
additional properties when processing the request.

Stating that additional props MUST not be a part of the request indicates that doing so is non-compliant and illegal. Contradicting the statement further on - that such properties MUST be ignored.

I think the idea with #278 is to make sure implementors don't use anything other than extensions under any circumstances. IMHO, we have two options:

  1. Use a SHOULD instead, and leave things as-is
  2. Leave the MUST, and make sure (with tests) that servers don't accept additional props

@Shane32
Copy link
Contributor Author

Shane32 commented Jan 26, 2024

I feel that it will hamper further extensions to the protocol if option 2 is selected.

@Shane32
Copy link
Contributor Author

Shane32 commented Jan 26, 2024

Well, we are basically stating that CLIENT implementations that are compatible with this version of the spec MUST not use other root props, and SERVER implementations MUST ignore additional props, in case of future expansion.

If we simply change the MUST to SHOULD, it still doesn't state why it's should vs must, being that the previous sentence stated that all other props are reserved. And doesn't state specifically that other keywords should be ignored.

I'd be fine changing to MUST to SHOULD but I'd still keep the additional sentence for clarification.

@benjie
Copy link
Member

benjie commented Jan 29, 2024

If I understand what you're saying correctly then I disagree with you @enisdenjo.

I'm writing this without yet reading the PR changes, because I want to get my thoughts straight first.


All other top-level keys in a request are reserved for future usage (note: which includes official extensions such as persisted operations) and thus clients implementing this version of the specification MUST NOT send additional keys at this top level - instead they may add extra information to extensions.

All other top-level keys in a request are reserved for future usage, but we will do our best to ensure that this future usage degrades gracefully, and thus servers that implement this version of the specification MUST IGNORE all other top-level keys.

Note: I've put this as a "must" for now, but we could loosen it to a "should" at a later time if need be.


In future editions (or with future extensions such as persisted operations, query batching, requesting the response in a different style/format/etc, doing something akin to ETag, adding some kind of smart patching, etc etc) clients may send additional keys; and these new clients may send requests to existing (legacy) servers. These servers cannot understand those keys, but because we want the future client to work with legacy servers, it's essential that legacy servers just ignore the additional keys such that the request degrades gracefully. Should we make a request that would no longer make sense without the additional keys, then we must do so by explicitly breaking the request format for legacy servers - for example removing the query field such that it becomes invalid and adding an id field instead (persisted operations).

Note that rejecting queries with additional keys would be the opposite of ignoring them. Instead, we could write tests that add additional keys of various types and assert that the behavior of the server is unchanged. Note, however, that these keys should be nonsensical, since a server may support future behaviours that our test suite does not yet understand (e.g. they may accept id as part of persisted operations) - I suggest you use UUIDs or other random strings as the keys you test.

Copy link
Member

@benjie benjie left a comment

Choose a reason for hiding this comment

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

Generally in favour of this, good to be explicit 👍

spec/GraphQLOverHTTP.md Outdated Show resolved Hide resolved
Co-authored-by: Benjie <benjie@jemjie.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants