Annotations
What Annotations Are
Annotations attach metadata to schema nodes.
@deprecated
type OldUser {
id string
}The VDL core does not hardcode most domain behavior. Plugins read annotations and decide what they mean.
For example, one plugin may interpret @event, another may interpret @rpc, and another may interpret @deprecated.
Basic Syntax
An annotation starts with @ and a name.
@internal
type InternalUser {
id string
}Annotations can also have one argument.
@deprecated("Use NewUser instead.")
type OldUser {
id string
}The argument must be a data literal: string, number, boolean, object, array, constant reference, or enum member reference.
Multiple Annotations
You can stack annotations.
@internal
@owner("platform")
type InternalConfig {
name string
}Annotations attach to the declaration or member that immediately follows them.
Declaration Annotations
Annotations can be attached to type, enum, and const declarations.
@event("users.created.{userId}")
type UserCreated {
userId string
email string
}
@stable
enum Region {
Europe = "eu"
America = "us"
}
@config
const serviceName = "billing"Field Annotations
Fields can have annotations.
type User {
@id
id string
@deprecated("Use displayName instead.")
name? string
displayName string
}Enum Member Annotations
Enum members can have annotations.
enum Plan {
Free = "free"
@deprecated("Use Team instead.")
Startup = "startup"
Team = "team"
}Object Arguments
Object arguments are useful for structured metadata.
@meta({ owner "platform" tier "gold" })
type Account {
id string
}Object entries use VDL literal syntax: key followed by value, no colon, no comma.
Array Arguments
@tags(["public" "billing" "stable"])
type Invoice {
id string
}Array literal items must be the same kind.
Annotation Names
Annotation names should use camelCase.
@generateClient
type PublicApi {
name string
}Avoid underscores or PascalCase annotation names.
Annotations Are Plugin Contracts
An annotation has no effect unless some tool or plugin understands it.
This is a feature. It lets teams create domain-specific contracts without changing the VDL grammar.
Examples:
@rpccan mark a type as an RPC service.@proccan mark a request/response RPC operation.@streamcan mark a server-sent stream operation.@event("subject.{field}")can mark an event payload and routing subject.@deprecatedcan mark generated code or schema output as deprecated.
Always check the plugin documentation for the annotations it supports.