Directives Reference

All GraphLink directives with arguments, placement, and examples.

@glCache

Target: CLIENT  ·  Placement: FIELD_DEFINITION on Query fields

Caches the result of a query field. The generated client checks the cache before making a network request and stores the result on a cache miss.

ArgumentTypeRequiredDescription
ttlInt!YesTime-to-live in seconds.
tags[String!]NoTags to associate with this cache entry for group invalidation.
staleIfOfflineBooleanNoWhen true, return the expired cached value if the network request fails.
Example GraphQL
type Query {
  getVehicle(id: ID!): Vehicle! @glCache(ttl: 120, tags: ["vehicles"])
  getUserProfile(id: ID!): UserProfile @glCache(ttl: 60, tags: ["users"], staleIfOffline: true)
  getConfig: AppConfig! @glCache(ttl: 3600)
}

@glCacheInvalidate

Target: CLIENT  ·  Placement: FIELD_DEFINITION on Mutation fields

Invalidates cache entries after a successful mutation. Either specify tags to evict by tag, or set all: true to wipe the entire cache.

ArgumentTypeDescription
tags[String!]Evict all entries tagged with any of these values.
allBooleanWhen true, evict the entire cache store.
Example GraphQL
type Mutation {
  addVehicle(input: AddVehicleInput!): Vehicle! @glCacheInvalidate(tags: ["vehicles"])
  updatePerson(input: UpdatePersonInput!): Person! @glCacheInvalidate(tags: ["persons", "vehicles"])
  resetDatabase: Boolean! @glCacheInvalidate(all: true)
}

@glTypeName

Target: CLIENT  ·  Placement: OBJECT, INPUT_OBJECT, ENUM

Overrides the name of the generated class for a type. By default, GraphLink uses the GraphQL type name. Use this when you need a different class name in the target language.

ArgumentTypeDescription
nameString!The class name to use in generated code.
Example GraphQL
# GraphQL type is "GQLVehicle", but generated class will be named "Vehicle"
type GQLVehicle @glTypeName(name: "Vehicle") {
  id: ID!
  brand: String!
}

@glDecorators

Target: SERVER  ·  Placement: OBJECT, INPUT_OBJECT

Adds raw annotation strings to the generated class declaration. Useful for adding JPA annotations (@Entity, @Table), Lombok annotations, or any other annotation that belongs on the class.

ArgumentTypeDescription
value[String!]!List of annotation strings to emit before the class declaration.
Example GraphQL
type Vehicle @glDecorators(value: ["@Entity", "@Table(name = \"vehicles\")"]) {
  id: ID!
  brand: String!
  model: String!
}

Generated output:

Generated Vehicle.java Java
@Entity
@Table(name = "vehicles")
public class Vehicle {
    // ...
}

@glSkipOnServer

Target: BOTH  ·  Placement: OBJECT, SCALAR

Instructs GraphLink to skip generating a class for this type in server mode. If mapTo is provided, the generator substitutes the given class name wherever this type appears.

ArgumentTypeDescription
mapToStringOptional. Fully-qualified class name to use in place of this type.
Example GraphQL
# Don't generate a class — use Spring Data's Pageable from the framework
type Pageable @glSkipOnServer(mapTo: "org.springframework.data.domain.Pageable") {
  page: Int
  size: Int
  sort: String
}

@glSkipOnClient

Target: BOTH  ·  Placement: OBJECT, INPUT_OBJECT, SCALAR

Instructs GraphLink to skip generating a class for this type in client mode. Use this for server-side types that clients never need to instantiate directly.

Example GraphQL
# PageInfo is part of GraphQL responses but clients don't instantiate it
type PageInfo @glSkipOnClient {
  hasNextPage: Boolean!
  endCursor: String
}

@glExternal

Target: BOTH  ·  Placement: SCALAR, OBJECT

Maps a GraphQL scalar or type to an external class, optionally specifying the import path. Unlike typeMappings in the config (which works for all types globally), @glExternal is per-type and can specify an import statement.

ArgumentTypeDescription
glClassString!The fully-qualified class name to use.
glImportStringOptional import statement to add to generated files that reference this type.
Example GraphQL
# Map the DateTime scalar to Java's OffsetDateTime
scalar DateTime @glExternal(
  glClass: "OffsetDateTime",
  glImport: "java.time.OffsetDateTime"
)

# Map the BigDecimal scalar to Java's BigDecimal
scalar BigDecimal @glExternal(
  glClass: "BigDecimal",
  glImport: "java.math.BigDecimal"
)

@glServiceName

Target: SERVER  ·  Placement: OBJECT

Sets a custom name for the generated service interface associated with a type. By default, the service is named {TypeName}Service. Use this when two types would produce the same service name, or when you prefer a domain-specific name.

ArgumentTypeDescription
nameString!The service interface name to generate.
Example GraphQL
# Generates FleetManagementService instead of VehicleService
type Vehicle @glServiceName(name: "FleetManagementService") {
  id: ID!
  brand: String!
}

@glEqualsHashcode

Target: BOTH  ·  Placement: OBJECT, INPUT_OBJECT

Generates equals() and hashCode() methods on the produced class, based on the specified fields. In Dart, generates == and hashCode overrides. In Java, generates standard equals/hashCode based on the listed fields.

ArgumentTypeDescription
fields[String!]!The field names to include in equality comparison.
Example GraphQL
# Two Vehicles are equal if they have the same id
type Vehicle @glEqualsHashcode(fields: ["id"]) {
  id: ID!
  brand: String!
  model: String!
}

# Two AddVehicleInputs are equal if all fields match
input AddVehicleInput @glEqualsHashcode(fields: ["brand", "model", "year", "fuelType"]) {
  brand: String!
  model: String!
  year: Int!
  fuelType: FuelType!
}

@glRepository

Target: SERVER  ·  Placement: OBJECT

Generates a JPA JpaRepository interface for this type. Requires generateRepositories: true in the server config. The repository is named {TypeName}Repository.

ArgumentTypeDescription
glTypeString!The entity class name (usually the same as the type, unless @glTypeName was used).
glIdTypeString!The Java type of the ID field (e.g. "String", "Long", "UUID").
Example GraphQL
type Vehicle @glRepository(glType: "Vehicle", glIdType: "String") {
  id: ID!
  brand: String!
}

Generated output (when generateRepositories: true):

Generated VehicleRepository.java Java
import org.springframework.data.jpa.repository.JpaRepository;

public interface VehicleRepository extends JpaRepository<Vehicle, String> {
}

@glInternal

Target: BOTH  ·  Placement: OBJECT

Marks a type as internal to the GraphLink runtime. Internal types are excluded from _all_fields fragment generation and from any UI widget generation (if using a framework plugin). Use this for generated infrastructure types like error wrappers or pagination metadata that should not appear in user-facing code.

Example GraphQL
# This type will not get an _all_fields fragment and will be skipped by UI generators
type GraphLinkError @glInternal {
  message: String!
  locations: [GraphLinkErrorLocation]
  path: [String]
}

@glValidate

Target: SERVER  ·  Placement: FIELD_DEFINITION on Mutation fields

Generates a validate{OperationName}() method in the service interface. The generated controller calls this method before the main operation method. Throw any exception in the validate method to abort the mutation.

Example GraphQL
type Mutation {
  addVehicle(input: AddVehicleInput!): Vehicle! @glValidate
}

Generated service interface additions:

Generated VehicleService.java Java
public interface VehicleService {
    // Called before addVehicle — throw to reject
    void validateAddVehicle(AddVehicleInput input);

    Vehicle addVehicle(AddVehicleInput input);
    // ...
}

@glArray

Target: BOTH  ·  Placement: FIELD_DEFINITION

By default, GraphLink generates list fields as List<T> (Java) or List<T> (Dart). Use @glArray on a field to generate a native array instead (T[] in Java, List<T> in Dart remains the same since Dart arrays and lists are unified).

Example GraphQL
type Person {
  id: ID!
  # Generated as Vehicle[] in Java instead of List<Vehicle>
  vehicles: [Vehicle!]! @glArray
}

Generated Java field:

Generated Person.java — with @glArray Java
public class Person {
    private String id;
    private Vehicle[] vehicles; // array instead of List<Vehicle>
    // ...
}

_all_fields — the magic fragment

When generateAllFieldsFragments: true is set in the config, GraphLink generates a named fragment for every type in the schema. The fragment selects all fields of that type and is named _all_fields_{TypeName}:

Generated _all_fields_Vehicle fragment GraphQL
fragment _all_fields_Vehicle on Vehicle {
  id
  brand
  model
  year
  fuelType
  ownerId
}

You can reference these fragments in hand-written queries as a shorthand:

Using _all_fields in a query GraphQL
query getVehicle($id: ID!) {
  getVehicle(id: $id) {
    ... _all_fields_Vehicle
  }
}

# Or use the shorthand — resolves to the type-appropriate fragment
query getVehicle($id: ID!) {
  getVehicle(id: $id) {
    ... _all_fields
  }
}

The shorthand ... _all_fields (without the type suffix) is resolved by GraphLink based on the return type of the field. It is equivalent to writing ... _all_fields_Vehicle when the field returns Vehicle.

The autoGenerateQueries: true config option uses these fragments internally to generate query strings for every operation in the schema — you never write query strings by hand at all.

Types annotated with @glInternal are excluded
Internal types (annotated with @glInternal) do not get _all_fields fragments. This prevents GraphLink's own runtime types from being included in user queries.