Annotations#
Annotations attach metadata to declarations. The grammar also supports annotation declarations, which describe annotation parameters, properties, and methods.
Annotation use#
@http(GET)
@audited(entity: "Vendor")
function list_vendors(company_code: CompanyCode): Json {
return {};
}Many declarations accept leading annotations, including fields, tables, functions, messages, structs, forms, apps, controls, modules, programs, resources, deployments, and subscriptions.
Annotation declarations#
Annotation declarations use an annotation name, a parenthesized parameter list, and a body. The parentheses are required even when there are no parameters.
Declaration parameters use the normal typed parameter syntax and may include default expressions.
@Audited(entity: string) {
enabled: bool = true;
reason(code: string): string {
return code;
}
}@Route(method: string = "GET", path: string) {
enabled: bool = true;
}Annotation members are typed properties with optional defaults or methods with typed return values and block bodies. Property semicolons are optional; method bodies are blocks.
@Internal() {
reason: string;
}Properties and methods#
Annotation properties use name: Type and may provide a default expression.
@Cacheable() {
ttl_seconds: int = 300;
key_prefix: string;
}Annotation methods use typed parameters, a return type, and a block body.
@Route(method: string, path: string) {
cache_key(company_code: CompanyCode, id: uuid): string {
return company_code + ":" + id;
}
}Use annotation methods for reusable metadata calculations. Do not use them as a hidden configuration resolver.
Design guidance#
Use annotations for metadata that affects tooling, exposure, tracing, generation, or runtime integration. Do not use annotations as a hidden place for tenant-configurable policy. Configurable business behavior belongs in tables and resolver functions.