directive @graphql

The @graphql directive specifies the GraphQL endpoint for a Query or Mutation field. When the field is resolved, a request is made to the GraphQL endpoint with a generated GraphQL operation. A field annotated with @graphql can populate a deep tree from a GraphQL endpoint. For example, if a GraphQL endpoint supports Customer and Address types such as:

type Customer {
  id:ID!
  name:String
  address:Address
}
type Address {
  street:String
  city:String
  zip:String
}

then a Query field defined as:

extend type Query {
  customer(id:ID):Customer @graphql(endpoint:"$url" configuration:"gql")
}

will resolve fields in Customer and Address. In this case the selection against Query.customer will result in an equivalent selection in the generated GraphQL operation.

Any type supported by the GraphQL endpoint can be extended in the schema to provide additional functionality, for example:

extend type Address {
  weather:Weather @materializer(query:"weatherFromZip")
}

Then when a request is made:

{customer(id:1) {name address {city weather {rainChance}}}}

the GraphQL endpoint for customer will receive an operation equivalent to:

{customer(id:1) {name address {city zip}}}

The field Customer.weather will be resolved using Query.weatherFromZip and incorporated into the final response.

It is important to note that @graphql performs an HTTP POST request to the specified endpoint with a content type of application/json

The HTTP request will have an Accept header set to application/graphql-response+json,application/json;q=0.8 unless the Accept header is set in @graphql(headers:).

The generated GraphQL operation's document including variable names, is not guaranteed to be consistent and may change at any time, due to batching or operation optimization.

Expansion variables

Expansion variables refer to values that can be used within the endpoint, and headers directive arguments. They follow the format $name or $name;.

An expansion variable is replaced by the:

  1. named value in the configuration (referenced by @graphql(configuration:) argument)

  2. JWT private claims from the incoming request when enabled

  3. named field argument

  4. injected expansion variables from @inject

These expansion variables are automatically into the configuration:

  • __host__ is replaced by the hostname of the incoming request, for example: alice.us-east-a.ibm.stepzen.net

  • __environment__ is replaced by the environment (account) name of the incoming request, for example: alice,

When a field argument is used as an expansion variable, it is not forwarded to the backend GraphQL endpoint.

Batching

Batching combines multiple compatible @graphql field resolutions in an incoming GraphQL request into a single backend outgoing GraphQL request. The generated operation document contains the required selections for all of the batched fields.

The maximum number of top-level fields in a batch defaults to 100 and can be overriden by setting batch.maxsize in the configuration entry. Setting batch.maxsize: 1 disables batching for any @graphql annotated field using that configuration.

A batch can wait for additional fields within the same incoming GraphQL request up to a timeout with a default value of 10ms. The timeout can be overriden by setting batch.timeout in the configuration entry. You must specify the timeout using one of the following time units, denoted by these suffixes: ns (nanoseconds), us (microseconds), ms (milliseconds), s (seconds).

Increasing the timeout can reduce the number of calls to a backend GraphQL endpoint at the expense of latency of response to the incoming GraphQL request.

configurationset:
  - configuration:
      name: example-graphql
      url: https://api.example.com/test/graphql
      batch.maxsize: 1
      batch.timeout: 100ms

Arguments

cachepolicy: StepZen_CachePolicy

The cachepolicy argument defines the caching policy for the GraphQL request. If applied to a field of Query the default is { strategy: ON }. If applied to a field of Mutation the default is { strategy: OFF }.

configuration: String

The configuration argument specifies the configuration entry by name from the configurationset Configuration values provide a hidden database of values that can be used in endpoint and headers

Values for configuration keys name and id (optional) are made available through the admin API and therefore it is recommended that these values do not contain secrets. A convention is to use id to represent the GraphQL endpoint for usage in asset management and dependency tracking.

Values for configuration keys name and id (optional) are made available through the admin API and therefore it is recommended that these values do not contain secrets. A convention is to use id to represent the database server for usage in asset management and dependency tracking.

endpoint: String!

The endpoint argument defines the GraphQL endpoint URI.

You can use a variable from the named configuration as a complete URL for the endpoint, for example, endpoint:"$url"

forwardheaders: [String!]

The forwardheaders argument defines the list of headers forwarded from the incoming GraphQL HTTP request to the HTTP call made to endpoint. Nonexistent headers will be forwarded as empty headers. Headers rendered via configuration entries take priority.

Restriction: The header "Content-Type" is set to "application/json" and cannot be forwarded.

Exception: This restriction overrides the general rule for forwardheaders. If Content-Type is set via configuration, it takes precedence and will not be overwritten or forwarded.

headers: [StepZen_RequestHeader!]

The headers argument specifies a list of headers to be included in the request. All headers, including duplicates, are added in order. Headers rendered via configuration entries and forwardheaders appear first. The first Content-Type header will be accepted if contenttype is not set.

prefix: StepZen_GraphQLPrefix

The prefix argument defines whether the root operation fields and types are prefixed. When a prefix is defined then it is stripped from root operation type fields and type names when creating the request to the declared GraphQL endpoint.

tls: String

The tls argument specifies a separate TLS configuration entry by name from the configurationset. This allows for reusable TLS configurations that can be shared across multiple endpoints.

The referenced TLS configuration can contain:

  • cert: Client certificate in PEM format for mutual TLS (mTLS) authentication

  • key: Private key for the client certificate in PEM format

  • ca: Root certificate chain in PEM format for custom CA validation

This approach provides better separation of concerns between API configuration and TLS configuration, enabling easier management and reuse of TLS settings across different endpoints.

Locations

Type System: FIELD_DEFINITION

Examples

Not-prefixed

type Query {
  hero(episode: Episode): Character
    @graphql(
      endpoint: "https://stepzen-chester.us-east.a.ibm.stepzen.net/examples/starwars/graphql"
    )
}

A request selecting Query.hero will result in a GraphQL request containing a query operation (also selecting Query.hero) against the example Star Wars endpoint.

Prefixed

type Query {
  SW_hero(episode: Episode): SW_Character
    @graphql(
      endpoint: "https://stepzen-chester.us-east.a.ibm.stepzen.net/examples/starwars/graphql"
      prefix: {value: "SW_", includeRootOperations: true}
    )
}

A request selecting Query.SW_hero will result in a GraphQL request containing a query operation (selecting Query.hero) against the example Star Wars endpoint.

Any prefix in any type condition (for example ... on SW_Human {homePlanet}) is stripped when generating the query operation for the backend.

Federation within same environment

type Query {
  customers(filter: CustomerFilter): CustomerConnection
    @graphql(endpoint: "https://$__host__;/api/customers/graphql")
}

Use of $__host__ allows a schema to be independent of where it is deployed when federating against endpoints within the same environment.