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

[RFC] Custom Scalar Specification URLs #649

Merged
merged 25 commits into from
Apr 9, 2021

Conversation

eapache
Copy link
Member

@eapache eapache commented Nov 20, 2019

This PR contains the specification changes needed for #635.

@sungam3r
Copy link
Contributor

Relates to #633

@@ -146,6 +146,9 @@ type __Type {

# should be non-null for NON_NULL and LIST only, must be null for the others
ofType: __Type

# should be non-null for SCALAR only, must be null for the others
specifiedBy: String
Copy link
Contributor

Choose a reason for hiding this comment

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

It correlates to some extent with #300 .
If this extension of the introspection schema will be added, it is logical to expect that the proposed in #300 extension
should be also accepted. Now there is a second server directive besides @deprecated, which is provided through introspection as a special property. I have nothing against this, but I believe that we need to provide a way to get user directives through introspection too. It will be a consistent step.

Copy link
Member

Choose a reason for hiding this comment

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

@sungam3r there are some experiments on introspection extensions. Technically you can already today extend introspection but this alway comes with the danger that you violate a future specification.

@IvanGoncharov was experimenting on this one with GraphQL-js. At the moment you can put metadata on almost everything there. We do almost the same with hot chocolate. The next thing would be to allow to have something like extensions on introspection so that there is a point where you can cleanly extend the introspection types.

Doing this through directives brings some challenges since directives, specifically their arguments are input types that could bear challenges to automatically extend the introspection from those.

@IvanGoncharov maybe we should start a new discussion on that?

Copy link
Contributor

Choose a reason for hiding this comment

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

I have a separate graphql-dotnet branch in which directives are already returned via introspection. We use this forked preview version in production.

this alway comes with the danger that you violate a future specification.

I agree. It’s not scary for us. We need new features now, and not when they (possibly) appear in the specification.

Copy link
Member

Choose a reason for hiding this comment

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

@sungam3r i did mean that more from them perspective. Hc allows extending the introspection already for a couple of versions. But the user that does that has to know that he/she might violate a future spec. We just have a warning in the docs that you can do it but may run into an issue in the future.

```graphql example
scalar Time
scalar Url
scalar Time @specified(by: "https://tools.ietf.org/html/rfc3339")
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit "misleading" example because RFC3339 is normally used to describe date and time.
How about scalar DateTime @specified(by: "https://example.com/myDateTime") ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Using a non RFC link would also make it more clear that it is totally fine to come up with your scalar spec.

Copy link
Member

Choose a reason for hiding this comment

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

I think we all agreed to have a specific spec for datetime since it is based on the rfc but more narrow in its implementation. There should be a specific document outlining the rules for this one.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I might just take this out as an example until we have something more useful to link to.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, if I take it out it gets even more confusing because the other example to talk about in the paragraph above is URL and then it gets really hard to parse whether I'm talking about the URL scalar as an example, or the URL that you provide in the example to link to the specification.

I'll rename this to DateTime for now, with the expectation that when Andi's restricted datetime scalar format doc gets published we'll change the link to that.

@@ -232,13 +235,16 @@ actually valid. These kinds are listed in the `__TypeKind` enumeration.

Represents scalar types such as Int, String, and Boolean. Scalars cannot have fields.

A GraphQL type designer should describe the data format and scalar coercion
rules in the description field of any scalar.
A GraphQL type designer should provide use the `@specified` directive to provide
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: should use the

@andimarek
Copy link
Contributor

great work @eapache

@@ -343,9 +343,17 @@ client-specific primitive for time. Another example of a potentially useful
custom scalar is `Url`, which serializes as a string, but is guaranteed by
the server to be a valid URL.

When defining an additional scalar, GraphQL systems should use the `@specified`
directive to provide an RFC3986-compliant URI pointing to a human-readable
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think throughout we can replace RFC3986-compliant URI with just URL

RFC3986-compliant URI could be understood to include an ISBN for an academic paper or something like that, and the goal here is that a person can load this URL in a browser and go read the spec. URL is well understood with a single definition, so there's no need to qualify it further with which IETF RFC you're referring to.

m14t added a commit to m14t/graphql-js that referenced this pull request Dec 6, 2019
This in an implementation for a spec proposal:

* Spec proposal: [[RFC] Custom Scalar Specification URIs](graphql/graphql-spec#649)
* Original issue: [[RFC] Custom Scalar Specification URIs](graphql/graphql-spec#635)

Please let me know if I forgot something.
m14t added a commit to m14t/graphql-js that referenced this pull request Dec 6, 2019
This in an implementation for a spec proposal:

* Spec proposal: [[RFC] Custom Scalar Specification URIs](graphql/graphql-spec#649)
* Original issue: [[RFC] Custom Scalar Specification URIs](graphql/graphql-spec#635)
@@ -146,6 +146,9 @@ type __Type {

# should be non-null for NON_NULL and LIST only, must be null for the others
ofType: __Type

# should be non-null for SCALAR only, must be null for the others
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: Currently in my draft for the reference implementation graphql/graphql-js#2276, if you don't add the @specified directive to a scalar, specifiedBy will be null.

If that's the correct implementation, then perhaps this wording could be updated to something along the lines of:

Suggested change
# should be non-null for SCALAR only, must be null for the others
# should be a string or null for SCALAR only, must be null for the others

Copy link
Member Author

@eapache eapache Dec 10, 2019

Choose a reason for hiding this comment

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

Hmm, it's a good point but I think I'd prefer just replacing should with can or may.

@eapache eapache changed the title [RFC] Custom Scalar Specification URIs [RFC] Custom Scalar Specification URLs Dec 10, 2019
@eapache eapache force-pushed the custom-scalar-formats branch from d8ed061 to f72a146 Compare December 10, 2019 19:00
scalar Time
scalar Url
scalar UUID @specified(by: "https://tools.ietf.org/html/rfc4122")
scalar URL @specified(by: "https://tools.ietf.org/html/rfc3986")
Copy link
Member Author

Choose a reason for hiding this comment

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

@leebyron I changed the capitalization here from Url to URL because Uuid looked particularly gross, and the built-in is already ID not Id. It's a minor editorial thing but it's not really related to this RFC so I wanted to make sure it was ok.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems totally fine to me


Fields

* `kind` must return `__TypeKind.SCALAR`.
* `name` must return a String.
* `specifiedBy` may return a URL or {null}.
Copy link
Member

Choose a reason for hiding this comment

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

We don't have a URL type so it should be String.

Copy link
Member Author

Choose a reason for hiding this comment

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

maybe may return a String (in the form of a URL) or {null}. ?

@IvanGoncharov
Copy link
Member

IvanGoncharov commented Dec 15, 2019

@eapache bikeshedding: How about changing @specified(by: 'http://example.com') to @specifiedBy(url: 'http://example.com')
Pros:

  • Fewer chances to conflict with existing and previous directives
  • It's easier to figure out that you pass/get URL from the name, e.g. inside introspection we would have specifiedByURL instead of specifiedBy

@sungam3r
Copy link
Contributor

+1 for @specifiedBy(url: 'http://example.com')
-1 for specifiedByURL

This is a personal feelings, specifiedByURL causes some associations with the Hungarian notation, which has its drawbacks.

@eapache
Copy link
Member Author

eapache commented Dec 16, 2019

I'm weakly in favour of @specifiedBy(url:) instead of @specified(by:).

relevant IETF specifications.

```graphql example
scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
Copy link
Contributor

Choose a reason for hiding this comment

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

While implementing this in graphql/graphql-js#2276 @IvanGoncharov provided the following comment:

If at some point we decide to add UUID scalar into this library it would be a confusing example.
It's better to use some abstract scalar like Foo and https://example.com/foo_spec.

Question: Do we want to make that same change here as well? If so this likely applies to URL as well, and effects a few locations in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Point taken that it could become confusing, but it's not confusing yet, and there is definitely value in having a concrete example that lines up with use cases a lot of actual developers will run into. I'm planning to leave this as is, and we can change it if becomes an issue later.

m14t added a commit to m14t/graphql-js that referenced this pull request Dec 31, 2019
This in an implementation for a spec proposal:

* Spec proposal: [[RFC] Custom Scalar Specification URIs](graphql/graphql-spec#649)
* Original issue: [[RFC] Custom Scalar Specification URIs](graphql/graphql-spec#635)
m14t added a commit to m14t/graphql-wg that referenced this pull request Jan 2, 2020
I've been working on the [implementation](graphql/graphql-js#2276) of the `@specified(by: "")` directive as specified by graphql/graphql-spec#649, and am interested an any feedback or progress on that effort.
@IvanGoncharov
Copy link
Member

Reviewing graphql/graphql-js#2276 I saw another argument for naming argument url instead of by, since by by itself looks weird in code:
https://github.com/graphql/graphql-js/pull/2276/files#diff-71ba52e9c625f826d2b0df2963c8633aR328

m14t added a commit to m14t/graphql-wg that referenced this pull request Jan 9, 2020
I've been working on the [implementation](graphql/graphql-js#2276) of the `@specified(by: "")` directive as specified by graphql/graphql-spec#649, and am interested an any feedback or progress on that effort.
@leebyron leebyron added the 📄 Draft (RFC 2) RFC Stage 2 (See CONTRIBUTING.md) label Jan 10, 2020
@leebyron leebyron force-pushed the custom-scalar-formats branch from 1758a1c to cb92ed5 Compare January 11, 2020 01:37
@leebyron leebyron force-pushed the custom-scalar-formats branch from c2e404e to 318b753 Compare April 9, 2021 06:01
@leebyron leebyron merged commit d4a865a into graphql:main Apr 9, 2021
leebyron added a commit that referenced this pull request Apr 16, 2021
One last follow up to #649 RFC, this uses the new term definition syntax and ensures the term usage is consistent throughout the document.

Also makes a minor editorial change in the introspection section to list the `description` field under `name` like the other sections
leebyron added a commit that referenced this pull request Apr 16, 2021
One last follow up to #649 RFC, this uses the new term definition syntax and ensures the term usage is consistent throughout the document.

Also makes a minor editorial change in the introspection section to list the `description` field under `name` like the other sections
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏁 Accepted (RFC 3) RFC Stage 3 (See CONTRIBUTING.md)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants