Contract Reference

Reference for valid @tag locations, names, contract errors, and more


This feature is only available with a GraphOS Enterprise plan. You can test it out by signing up for a free GraphOS trial. To compare GraphOS feature support across all plan types, see the pricing page.

Rules for @tags 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.

GraphQL
1type User {
2  id: ID!
3  name: String! @tag(name: "a/b/c/1-2-3")
4}

Dependent @tags

  • 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:

    GraphQL
    1type 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:

    GraphQL
    1type BillingAccount @tag(name: "internal") {
    2  id: ID!
    3  acctNumber: String!
    4}
    5
    6type Query {
    7  billingAccounts: [BillingAccount!]! @tag(name: "internal")
    8}
    ⚠️ caution
    If 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:

      GraphQL
      1# 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:

    GraphQL
    1# 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:

    GraphQL
    1# This object type is excluded because all its fields are excluded.
    2type User {
    3  id: ID! @tag(name: "excludeMe")
    4}
    ⚠️ caution
    This 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:

    GraphQL
    1# 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}
    ⚠️ caution
    This 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
ADD_DIRECTIVE_DEFINITIONS_IF_NOT_PRESENT
An error occurred adding directive definitions for @tag, @inaccessible, and core directive usages.
DIRECTIVE_DEFINITION_LOCATION_AUGMENTING
An error occurred augmenting the directive definition for @tag to support OBJECT, FIELD_DEFINITION, INTERFACE, and UNION.
EMPTY_OBJECT_AND_INTERFACE_MASKING
All of an object or interface type's fields were excluded, and an error occurred while excluding the entire type.
EMPTY_UNION_MASKING
All of a union type's included types were excluded, and an error occurred while excluding the entire union.
INPUT_VALIDATION
The contract is attempting to include and exclude the same tag.
PARSING
After including and excluding fields, the resulting contract schema failed to parse.
PARSING_TAG_DIRECTIVES
GraphOS encountered an error while trying to obtain all uses of @tag from the source variant schema.
PARTIAL_INTERFACE_MASKING
An interface field's return type was excluded, and an error occurred while excluding that interface field.
SCHEMA_RETRIEVAL
GraphOS encountered an error while retrieving the source variant's schema. It might not yet have a valid composed schema.
TAG_INHERITING
GraphOS encountered an error while attempting to add parent tags to fields.
TAG_MATCHING
GraphOS encountered an error determining which types and fields should be inaccessible based on their tags.
TO_API_SCHEMA
GraphOS encountered an error while attempting to generate an API schema from the contract variant's supergraph schema.
TO_FILTER_SCHEMA
GraphOS failed to generate and return a contract supergraph schema for an unknown reason.
UNKNOWN
An unknown error occurred.
UNREACHABLE_TYPE_MASKING
GraphOS encountered an error while attempting to exclude unreachable types in the resulting contract schema.
VERSION_CHECK
Contracts do not support the Federation version used.