link v1.0
for linking schemas together
Status | Draft |
Version | 1.0 |
@link other schemas by their URL and import:
definitions from them.
1@link
Link a foreign schema and optionally import definitions.
1.1url: String!
The foreign schema’s URL.
Link URLs serve two main purposes:
- Providing a unique identifier for the foreign schema
- Directing human readers to documentation about the foreign schema
Link URLs SHOULD be RFC 3986 URLs. When viewed, the URL SHOULD provide schema documentation in some human‐readable form—a human reader should be able to click the link and go to the correct version of the docs. This is not an absolute functional requirement—as far as the core schema machinery is concerned, the URL is simply a globally unique namespace identifier with a particular form.
If url:
is not a valid RFC 3986 url, then it MUST be treated as an opaque identifier for the foreign schema. Such non‐URL inputs to url:
SHOULD NOT have name and version information extracted from them—both are null.
Link URLs which are valid urls MAY contain information about the spec’s name and version:
The final two segments of the URL’s path MAY contain the schema’s name and a version tag, in that order. Both are optional. To be recognized as a version tag, the final path component MUST be a valid VersionTag. To be recognized as a name, the penultimate path component MUST be a valid GraphQL name which does not start or end with an underscore (_
) and which does not contain the namespace separator (__
).
Empty final path components (that is, trailing slashes) and any URL components which have not been assigned a meaning (such as the fragment and query) MUST be ignored.
All of these are valid arguments to url
, and their interpretations:
url | normalized url | name | version |
---|---|---|---|
https://spec.example.com/a/b/mySchema/v1.0/ | https://spec.example.com/a/b/mySchema/v1.0 | mySchema | v1.0 |
https://spec.example.com | https://spec.example.com | (null) | (null) |
https://spec.example.com/mySchema/v0.1?q=v#frag | https://spec.example.com/mySchema/v0.1 | mySchema | v0.1 |
https://spec.example.com/v1.0 | https://spec.example.com/v1.0 | (null) | v1.0 |
https://spec.example.com/vX | https://spec.example.com/vX | vX | (null) |
If name
is present, that namespace prefix will automatically be linked to the URL. If a name
is not present, then elements of the foreign schema must be imported
in order to be referenced.
1.2as: String
Change the namespace prefix assigned to the foreign schema. The name MUST be a valid GraphQL identifier, MUST NOT contain the namespace separator ("__"), and MUST NOT end with an underscore (which would create ambiguity between whether "x___y" is prefix x_
for element y
or prefix x
for element _y
).
By default, @link will assign a prefix based on the name
extracted from the URL. If no name
is present, a prefix will not be assigned.
Providing as:
overrides the default behavior: the foreign schema will be bound to the provided name, regardless of the name
present in the URL (or the lack of one).
1.3import: [Import]
A list of elements, possibly with aliases, to import from the foreign schema into the document.
Importing an element gives it a local, non‐namespaced name.
See the Import scalar for a description of the argument format.
1.4for: Purpose
An optional purpose for this link. This hints to consumers as to whether they can safely ignore metadata described by a foreign schema.
By default, @links SHOULD fail open. This means that @links to unknown schemas SHOULD NOT prevent a schema from being served or processed. Instead, consumers SHOULD ignore unknown links and serve or process the rest of the schema normally.
This behavior is different for @links with a specified purpose:
SECURITY
links convey metadata necessary to compute the API schema and securely resolve fields within itEXECUTION
links convey metadata necessary to correctly resolve fields within the schema
2Import
An element, possibly aliased, to import into the document.
Import can take the form of a string:
or an object with name
and (optionally as
):
name
and as
MUST be of the same type:
Imports cannot currently reference transitive schemas:
3Purpose
The role of a @linked schema.
This is not intended to be an exhaustive list of all the purposes a foreign schema or its metadata might serve. Rather, it is intended to capture cases where the default fail‐open behavior of core schema consumers is undesirable.
for: SECURITY
or for: EXECUTION
as “SECURITY
directives” and “EXECUTION
directives”, respectively.3.1SECURITY
SECURITY
links provide metadata necessary to securely resolve fields. For instance, a hypothetical auth schema may provide an @auth directive to flag fields which require authorization. If a data core does not support the auth schemas and serves those fields anyway, these fields will be accessible without authorization, compromising security.
Security‐conscious consumers MUST NOT serve a field if:
- the schema definition has any unsupported SECURITY directives,
- the field’s parent type definition has any unsupported SECURITY directives,
- the field’s return type definition has any unsupported SECURITY directives, or
- the field definition has any unsupported SECURITY directives
Such fields are not securely resolvable. Security‐conscious consumers MAY serve schemas with fields which are not securely resolvable. However, they MUST remove such fields from the schema before serving it.
Less security‐conscious consumers MAY choose to relax these requirements. For instance, servers may provide a development mode in which unknown SECURITY directives are ignored, perhaps with a warning. Such software may also provide a way to explicitly disable some or all SECURITY links during development.
More security‐conscious consumers MAY choose to enhance these requirements. For instance, production servers MAY adopt a policy of entirely rejecting any schema which contains ANY unsupported SECURITY links, even if those links are never used to annotate the schema.
3.2EXECUTION
EXECUTION
schemas provide metadata necessary to correctly resolve fields. For instance, a hypothetical ts schemas may provide a @ts__resolvers
annotation which references a TypeScript module of field resolvers. A consumer which does not support the ts schemas will be unable to correctly resolve such fields.
Consumers MUST NOT serve a field if:
- the schema’s definition has any unsupported EXECUTION directives,
- the field’s parent type definition has any unsupported EXECUTION directives,
- the field’s return type definition has any unsupported EXECUTION directives, or
- the field definition has any unsupported EXECUTION directives
Such fields are unresolvable. Consumers MAY attempt to serve schemas with unresolvable fields. Depending on the needs of the consumer, unresolvable fields MAY be removed from the schema prior to serving, or they MAY produce runtime errors if a query attempts to resolve them. Consumers MAY implement stricter policies, wholly refusing to serve schemas with unresolvable fields, or even refusing to serve schemas with any unsupported EXECUTION schemas, even if those schemas are never used in the schema.