federation v1.0
| Status | Release |
| Version | 1.0 |
1@key
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
The @key directive is used to indicate a combination of fields that can be used to uniquely identify and fetch an object or interface.
type Product @key(fields: "upc") {
upc: UPC!
name: String
}
Multiple keys can be defined on a single object type:
type Product @key(fields: "upc") @key(fields: "sku") {
upc: UPC!
sku: SKU!
name: String
}
@key, used multiple times) require support by the underlying GraphQL implementation.2@provides
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
The @provides directive is used to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. Given the following example:
type Review @key(fields: "id") {
product: Product @provides(fields: "name")
}
extend type Product @key(fields: "upc") {
upc: String @external
name: String @external
}
When fetching Review.product from the Reviews service, it is possible to request the name with the expectation that the Reviews service can provide it when going from review to product. Product.name is an external field on an external type which is why the local type extension of Product and annotation of name is required. “””
3@requires
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
The @requires directive is used to annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. For example:
# extended from the Users service
extend type User @key(fields: "id") {
id: ID! @external
email: String @external
reviews: [Review] @requires(fields: "email")
}
In this case, the Reviews service adds new capabilities to the User type by providing a list of reviews related to a user. In order to fetch these reviews, the Reviews service needs to know the email of the User from the Users service in order to look up the reviews. This means the reviews field / resolver requires the email field from the base User type.
4@external
directive @external on FIELD_DEFINITION
The @external directive is used to mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. For example:
# extended from the Users service
extend type User @key(fields: "email") {
email: String @external
reviews: [Review]
}
This type extension in the Reviews service extends the User type from the Users service. It extends it for the purpose of adding a new field called reviews, which returns a list of Reviews.
5_FieldSet
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
directive @external on FIELD_DEFINITION
scalar _FieldSet
# this is an optional directive
# used in frameworks that don't natively support GraphQL extend syntax
directive @extends on OBJECT | INTERFACE
A set of fields.
@keytype User @key(fields: "id") {
id: ID! @external
}
type User @key(fields: "uid realm") {
uid: String
realm: String
}
Deeply nested fields are supported with standard GraphQL syntax
type User @key(fields: "contact { email }") {
contact: Contact
}
type Contact {
email: String
}
Field arguments are not supported.
type User @key(fields: "emails(first: 1)") {
emails(first: Int): [String]
}