-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Service capabilities #1208
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
base: main
Are you sure you want to change the base?
Service capabilities #1208
Conversation
✅ Deploy Preview for graphql-spec-draft ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
|
||
| ServiceCapability : Description? capability QualifiedName ServiceCapabilityValue? | ||
|
|
||
| ServiceCapabilityValue : ( StringValue ) |
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.
why not
ServiceCapabilityArgument : ArgumentName: ConstantValue
ServiceCapabilityValue : ( ServiceCapabilityArgument+ )
Basically: why shouldn't we be able to use enum values or integers or have a service take in an input or etc? Seems like it'd be common to need 3-4 flags for one capability to work.
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.
Because we don't yet have the struct type which would be ideal for this.
But also, if you need multiple arguments (why?) either use custom serialization or use multiple capabilities.
service {
capability graphql.ws
capability graphql.ws.endpoint("ws://...")
"To avoid thundering herd, multiply this by `(0.5 + rand())`"
capability graphql.ws.reconnectDelay("3000")
"The modern protocol"
capability graphql.ws.protocol.graphqlTransportWs
"The updated modern protocol"
capability graphql.ws.protocol.graphqlTransportWs.v2
"Configuration for V2 protocol"
capability graphql.ws.protocol.graphqlTransportWs.v2.encoding("utf-8")
"The legacy protocol"
capability graphql.ws.protocol.graphqlWs
}Arguments should be the rarer case, IMO - if in doubt, use a sub-name (like the protocols above) rather than an argument.
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.
Do you have examples that don't fit this well?
(Extracted and reworked from the error behaviors PR (#1163) to stand alone, since it has broader utility and can progress faster alone.)
This PR introduces "service capabilities" - a mechanism for GraphQL services to advertise features and configuration that exist outside the type system - for example support for syntax features (executable descriptions, fragment arguments, document directives, etc), details of transport support (websocket endpoint, SSE endpoint, how to be notified of new schema versions), and other details that can enable automated client configuration.
Motivation
In addition to being a prerequisite of the error behaviors proposal, this is a desired feature for composite schemas and a key component of The GraphQL Golden Path Initiative (specifically enabling client auto-configuration).
The goal is that a user can point tooling at a GraphQL endpoint and much of the configuration can be implied based on the service's advertised capabilities - this massively reduces the amount of "out of band" communication required.
Example use cases:
@defer/@stream)? Which version?Why "capabilities" not "metadata"?
Capabilities inform automated tooling/client decisions and actions. Metadata is ancillary and often intended for human consumption. The name "capabilities" is intentional - it signals the purpose and discourages using this system as a dumping ground for arbitrary metadata. Every capability should be actionable by clients or tooling.
Design
Introspection via
__service: __Servicemeta-field (similar to__schema: __Schema):Support can be probed via:
{ __type(name: "__Service") { name } }- if no result, then the service does not support service capabilities.SDL syntax
Slightly changed from previous proposals, here's the syntax I now propose:
Notes on this choice:
service { capability foo.bar "Value" capability foo.baz }would apply"Value"as the description forfoo.bazrather than the value forfoo.bar)extendsyntax feels very naturalserviceproperties in futureservice @capability(identifier: "...", value: "...")), but theservicekeyword already introduces new syntax so it doesn't seem necessary to be constrained to using ugly directives when a neater and more palatable syntax is available; this also allows for descriptions for each capability.Capability identifiers
A
QualifiedNamesyntax (Name(.Name)+) inspired by reverse-domain notation encourages global uniqueness. Thegraphql.prefix is reserved for official GraphQL Foundation specifications (not just the main spec; e.g.graphql.http.*could be used by the GraphQL-over-HTTP spec).