Skip to content

Schema Coordinates #794

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

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

Conversation

magicmark
Copy link
Contributor

@magicmark magicmark commented Nov 18, 2020

👋

I've pulled out the proposed spec edits for Schema Coordinates (issue: #735) into this PR.

(The RFC now lives in the original PR: https://github.com/graphql/graphql-spec/pull/746/files)

@leebyron you mentioned it might be possible to simplify the grammar - I played around a bit since the original PR, but I think I need some help here. What did you have in mind?

As suggested, tagging @eapache @mjmahone as additional reviewers as we had some good conversation in last WG meeting about this.

Thanks!


GraphQL.js PR: graphql/graphql-js#3044

@magicmark
Copy link
Contributor Author

magicmark commented Nov 18, 2020

Oh also, here's another option I had for the examples table, was thinking it might be good to explicitly show all the different kinds of schema you can select:

Screen Shot 2020-11-17 at 10 38 01 PM

felt slightly too verbose to me, but curious to see if anyone prefers this

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.

Thanks for your hard work on this!

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.

Looks good to me; a few optional tweaks suggested.

Comment on lines 379 to 399
Schema Coordinates are always unique. Each type, field, argument, enum value, or
directive may be referenced by exactly one possible Schema Coordinate.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

feels like something worth highlighting and being clear about as a guarantee in the spec

Comment on lines 382 to 391
For example, the following is *not* a valid Schema Coordinate:

```graphql counter-example
Entity.Business
```

In this counter example, both `Entity.Business` and `Business` would refer to
the `Business` type. Since it would be ambiguous what the "primary key" should
be in an application that uses Schema Coordinates to reference types, this is
not allowed.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

is this waffle? thought it might be helpful to have a little explanation/demonstration of this property

Copy link
Contributor Author

@magicmark magicmark Jan 4, 2021

Choose a reason for hiding this comment

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

Could just be

- Since it would be ambiguous what the "primary key" should be in an application that uses Schema Coordinates to reference types, this is not allowed.
+ Such ambiguity is disallowed (and hence why this is is invalid syntax).

(More terse, but doesn't walk the reader through why this is bad)

Voting lines are now open!

Copy link
Member

Choose a reason for hiding this comment

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

In this counter example, Entity.Business is redundant since Business already uniquely identifies the Business type. Such redundancy is disallowed by this spec - every type, field, field argument, enum value, directive, and directive argument has exactly one canonical Schema Coordinate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 thanks benjie, stealing this wording

magicmark added a commit to magicmark/graphql-wg that referenced this pull request Jan 4, 2021
Happy new year! 🥳

It's possible we still want more time for the RFC to marinate, but I'll attend so I can be available to folks to discuss the schema coordinates rfc/spec edit in person.

graphql/graphql-spec#794

Thanks!
@leebyron leebyron added the 💡 Proposal (RFC 1) RFC Stage 1 (See CONTRIBUTING.md) label Jan 7, 2021
Base automatically changed from master to main February 3, 2021 04:50
@mcohen75
Copy link

mcohen75 commented Feb 4, 2021

At Indeed we log usage of schema elements to 1) support deprecation and 2) understand usage from a product management perspective (i.e. is this API we built adding value?).

We defined our own coordinate system that is not quite as complete as this spec. A nice benefit of formalizing a coordinate system is that shared tools can be built to solve these and other use cases.

👍 👍 👍

@leebyron leebyron added 📄 Draft (RFC 2) RFC Stage 2 (See CONTRIBUTING.md) and removed 💡 Proposal (RFC 1) RFC Stage 1 (See CONTRIBUTING.md) labels Mar 4, 2021
@leebyron leebyron added this to the May2021 milestone Apr 13, 2021
@leebyron leebyron force-pushed the schema_coordinates_spec_edit branch 3 times, most recently from 4f854af to c0b82d5 Compare April 13, 2021 23:57
@leebyron
Copy link
Collaborator

I made some fairly significant edits to the prose and examples section in an attempt to simplify. @magicmark please take a look and let me know what you think.

@leebyron leebyron force-pushed the schema_coordinates_spec_edit branch 3 times, most recently from 81ef020 to 4299d8c Compare April 14, 2021 01:18
@leebyron leebyron requested review from benjie and a team April 14, 2021 01:20
@leebyron leebyron changed the title Schema Coordinates: add spec edit Schema Coordinates Apr 14, 2021
@leebyron
Copy link
Collaborator

IIRC the only thing holding this from Approval stage is a landed GraphQL.js PR?

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.

There has been discussion around whether having the coordinate for a field and an enum value be the same makes sense. I propose that we change the syntax used for enum values from . to :::

Type # Any named type
Type.field # A field (e.g. on an object, interface, or inputObject type)
Type.field(argName:) # An argument (on an object or interface type)
Type::value # an Enum value (on an enum type)

:: is the syntax used to reference an enum value in C++, Rust, PHP, Perl and others, so it seems pretty natural.

I also think that doing this will make it more obvious for users reading a schema coordinate that it's an enum value being referenced rather than a field (and vice versa).

@benjie
Copy link
Member

benjie commented Jun 5, 2025

I have raised a PR to implement these changes here: magicmark#1

Use `::` syntax for enum values
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.

Everyone who has previously approved this PR should re-approve it with the new Type::VALUE syntax for enum values.

Copy link
Contributor

@martinbonnin martinbonnin left a comment

Choose a reason for hiding this comment

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

Looks great!

Just left a few unimportant nitpicks.
My main question is still around meta fields. I still think we should include them for consistency, simplicity and also because I want to monitor usage of meta fields as well.

@PascalSenn
Copy link
Contributor

In my opinion, using :: introduces several issues:

  • While this is still a proposal, schema coordinates are already an established part of the GraphQL ecosystem. Changing the format at this stage would require all existing GraphQL servers that have implemented the proposal to update their parsers, add backward compatibility for the old format, and potentially modify all related tooling. Tools that rely on schema coordinates to identify schema elements may break, need migration paths, or require compatibility layers.

  • If we decide to support union member coordinates in the future, the appropriate delimiter becomes ambiguous. Should it be Foo.Bar, Foo::Bar, or Foo->Bar?

  • From my perspective ( influenced by JS, TS, and C#), Foo.BAR naturally points to an enum member. In contrast, Foo::BAR feels less intuitive.

  • When looking up schema members via a schema coordinate, the choice of separator is irrelevant - both represent the same concept. Tooling on the other hand will likely require additional context anyway, since, for example, an input field differs fundamentally from an output field. So, do we really need a different separator? (@, Type, Member, Arg)

@benjie
Copy link
Member

benjie commented Jun 5, 2025

Conclusion from the WG was to:

a) support meta fields
b) use the same syntax for fields and enum values.

Sorry @JoviDeCroock, you were outvoted! I think your concerns have merit and hopefully I represented them well, but equally what we're primarily doing here is encoding a pattern we already see in the ecosystem and apparently people are actively encoding enum values like this (who knew? I only ever see schema coordinates used for types, fields, arguments and directives!) so "member" it is! 🤷

@benjie
Copy link
Member

benjie commented Jun 5, 2025

I didn't voice it during the call because we were already over time, but there are legitimate reasons why enum values might not always be CONSTANT_CASE; for example if you wish to allow filtering of an abstract type to only certain types you might do e.g.{ user { pets(only: [Cat, Dog]) { name } } } where Cat and Dog are enum values that exactly match the type names used in the schema (this is more obvious when the type names are formed of multiple words). There are other scenarios where CONSTANT_CASE is not a perfect fit, but I certainly agree that it should be the default for most things unless you have a very good reason.

@magicmark
Copy link
Contributor Author

magicmark commented Jun 6, 2025

Updates June 6th 2025:

  • I have reverted back to proposing MemberCoordinates (Name.Name) to refer to both object fields and enum values, per the WG discussion and reasoning above.
  • meta-fields are no longer disallowed (@leebyron doesn't remember why we added this restriction in the first place)
  • union members are still disallowed. I don't have super strong opinions for if we should allow that or not (I personally can't think of use cases we would have for that), but either way, my strong preference would be to tackle this in a future spec proposal should we decide to add support for that.

Implementation changes here: graphql/graphql-js#4432

yaacovCR pushed a commit to graphql/graphql-js that referenced this pull request Jun 9, 2025
This PR is applied to the `schema-coordinates` branch PR here: #3044

Implements schema coordinate spec changes per the June 5th 2025 WG discussion

graphql/graphql-spec#794

- Add support for meta-fields (e.g. `__typename`)
- Add support for introspection types
- Revert back from FieldCoordinate+ValueCoordinate -> MemberCoordinate

cc @benjie
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📄 Draft (RFC 2) RFC Stage 2 (See CONTRIBUTING.md) 🚀 Next Stage? This RFC believes it is ready for the next stage
Projects
None yet
Development

Successfully merging this pull request may close these issues.