Contract Reference
Reference for valid @tag locations, names, contract errors, and more
Rules for @tag
s and contracts
Valid @tag
locations
In both Federation 1 and Federation 2, you can apply tags to the following schema elements to filter your contract schema:
Object, interface, and union type definitions
Fields of object types
Federation 1 doesn't support tagging fields of interface types.
In Federation 1, you can still make an interface field inaccessible by tagging the interface definition or by ensuring that object fields that implement the interface field are removed.
In Federation 2 only, you can also apply tags to the following:
Fields of interface types
Enum types and their values
Input types and their fields
Definitions of custom scalar types
Arguments of fields, but not directive arguments
Valid @tag
names
@tag
names can include alphanumeric characters (a-z
,A-Z
,0-9
), along with hyphens (-
) and forward slashes (/
).Each tag name cannot exceed 128 characters.
1type User {
2 id: ID!
3 name: String! @tag(name: "a/b/c/1-2-3")
4}
Dependent @tag
s
Whenever you tag the definition of an object or interface type, GraphOS automatically considers that tag to be applied to all fields of that type:
GraphQL1type InternalUser @tag(name: "internal") { 2 id: ID! # Also considered to have @tag(name: "internal") 3}
Whenever you tag the definition of an object, interface, or union type, you should always apply that same tag to every field that returns that type:
GraphQL1type BillingAccount @tag(name: "internal") { 2 id: ID! 3 acctNumber: String! 4} 5 6type Query { 7 billingAccounts: [BillingAccount!]! @tag(name: "internal") 8}
⚠️ cautionIf you don't do this, a contract might exclude a type while including fields that return that type. This produces an invalid contract schema.If a contract excludes an object that implements an interface or is included in a union:
The contract is not required to exclude schema fields that return that interface or union as long as at least one other associated object type remains:
GraphQL1# Two object types implement this interface. 2interface Identity { 3 id: ID! 4 name: String! 5} 6 7# If this implementing type is excluded... 8type InternalUser implements Identity @tag(name: "internal") { 9 id: ID! 10 name: String! 11} 12 13# ...but this implementing type remains... 14type ExternalUser implements Identity { 15 id: ID! 16 name: String! 17} 18 19type Query { 20 # ...then this field doesn't need to be excluded. 21 currentIdentity: Identity 22}
However, if a subgraph resolves one of these fields by returning an object of an excluded type, a runtime error occurs in the router and the operation fails.
Special cases for filtering
If a contract defines a list of included
@tags
, any object or interface type without an included tag is still included in the contract schema if at least one of its fields is included:GraphQL1# This type definition is included because one if its fields is included. 2type User { 3 id: ID! @tag(name: "includeMe") 4}
If a contract excludes every field of an object or interface type, the entire type definition is excluded from the contract schema:
GraphQL1# This object type is excluded because all its fields are excluded. 2type User { 3 id: ID! @tag(name: "excludeMe") 4}
⚠️ cautionThis can produce an invalid contract schema if any fields that return the excluded type are included.If a contract excludes every object type that's part of a union type, the entire union type definition is excluded from the contract schema:
GraphQL1# This union type is excluded because all its possible types are excluded. 2union Media = Book | Movie 3 4type Book @tag(name: "excludeMe") { 5 title: String! 6} 7 8type Movie @tag(name: "excludeMe") { 9 title: String! 10}
⚠️ cautionThis can produce an invalid contract schema if any fields that return the excluded union type are included.A contract cannot exclude any of the following, even if tagged:
Built-in scalars (
Int
,Float
, etc.)Built-in directives (
@skip
,@include
, etc.)Custom directives that are applied to type system locations (see the list)
A contract can exclude object fields that are used in a computed field's
@requires
directive without causing runtime errors.
Errors
GraphOS may encounter the following errors when creating or updating a contract schema. Errors descriptions include the step in the creation process where the error occurred:
Error | Description |
---|---|
| An error occurred adding directive definitions for @tag , @inaccessible , and core directive usages. |
| An error occurred augmenting the directive definition for @tag to support OBJECT , FIELD_DEFINITION , INTERFACE , and UNION . |
| All of an object or interface type's fields were excluded, and an error occurred while excluding the entire type. |
| All of a union type's included types were excluded, and an error occurred while excluding the entire union. |
| The contract is attempting to include and exclude the same tag. |
| After including and excluding fields, the resulting contract schema failed to parse. |
| GraphOS encountered an error while trying to obtain all uses of @tag from the source variant schema. |
| An interface field's return type was excluded, and an error occurred while excluding that interface field. |
| GraphOS encountered an error while retrieving the source variant's schema. It might not yet have a valid composed schema. |
| GraphOS encountered an error while attempting to add parent tags to fields. |
| GraphOS encountered an error determining which types and fields should be inaccessible based on their tags. |
| GraphOS encountered an error while attempting to generate an API schema from the contract variant's supergraph schema. |
| GraphOS failed to generate and return a contract supergraph schema for an unknown reason. |
| An unknown error occurred. |
| GraphOS encountered an error while attempting to exclude unreachable types in the resulting contract schema. |
| Contracts do not support the Federation version used. |