clotho/docs/ANNOTATIONS.md
2026-05-15 00:09:01 +02:00

342 lines
7.2 KiB
Markdown

# Annotation Reference
## Class-Level Annotations
---
### `@VertexType`
Declares a class as a Clotho-managed vertex type. The class must extend `ClothoVertex`.
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface VertexType {
String value(); // ArcadeDB vertex type name (required)
String[] additionalParents() // ArcadeDB parent type names beyond Java hierarchy
default {}; // Use for diamond inheritance
String parentLabel() // Explicit ArcadeDB parent when Java hierarchy diverges
default "";
}
```
**Examples:**
```java
// Simple
@VertexType("Employee")
public class Employee extends ClothoVertex { }
// Abstract type
@VertexType("Person")
public abstract class Person extends ClothoVertex { }
// Diamond inheritance
@VertexType(value = "ContractEmployee", additionalParents = {"Contractor"})
public class ContractEmployee extends Employee { }
// Divergent Java/ArcadeDB hierarchy
@VertexType(value = "ExternalWorker", parentLabel = "Employee")
public class ExternalWorker extends ClothoVertex { }
```
---
### `@EdgeType`
Declares a class as a Clotho-managed edge type. The class must extend `ClothoEdge`.
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EdgeType {
String value(); // ArcadeDB edge type name (required)
}
```
**Example:**
```java
@EdgeType("WORKS_AT")
public class WorksAt extends ClothoEdge {
public static final String LABEL = "WORKS_AT";
// ...
}
```
Convention: define `LABEL` as a constant on the edge class to avoid magic strings at call
sites when referencing the label in `@Via`.
---
### `@SubgraphType`
Declares a composite type assembled from a Gremlin `select()` traversal. Must NOT extend
`ClothoVertex` or `ClothoEdge`. Has no ARID.
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SubgraphType {
}
```
**Example:**
```java
@SubgraphType
public class EmployeeProfile {
Employee employee;
Manager manager;
@Alias("dept") Department department;
List<WorksAt> workHistory;
}
```
---
## Field-Level Annotations
---
### `@RID`
Marks the field that holds the element's `ARID`. Inherited from `ClothoEntity`; generally
not needed unless overriding the base class field.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RID {
}
```
---
### `@Property`
Maps a field to an ArcadeDB vertex or edge property. Optional when the field name exactly
matches the property name.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Property {
String value(); // ArcadeDB property name
}
```
**Example:**
```java
@Property("startDate") LocalDate start; // field name differs from property name
LocalDate endDate; // no annotation needed; names match
```
---
### `@Include`
Marks a field as part of this object's eager-load boundary. Always paired with `@Via`.
The field type must be a `@VertexType` class, an `@EdgeType` class, or a `List<>` of either.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Include {
}
```
---
### `@Via`
Specifies the ArcadeDB edge label to traverse for an `@Include` field.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Via {
String value(); // Edge label (required)
}
```
**Strongly preferred pattern** — use the edge class's `LABEL` constant:
```java
@Include @Via(WorksAt.LABEL)
List<WorksAt> workHistory;
```
---
### `@Direction`
Specifies which edge direction to follow for an `@Include` + `@Via` traversal.
Defaults to `OUT` (or the global configured default).
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Direction {
Direction value() default Direction.OUT;
}
public enum Direction { OUT, IN, BOTH }
```
**Example:**
```java
@Include @Via("ASSIGNED_TO") @Direction(Direction.IN)
List<Task> assignedTasks;
```
---
### `@OutVertex`
On an `@EdgeType` class: marks the field holding the out-vertex (source) of the edge.
The field type must be a `@VertexType` class.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OutVertex {
}
```
---
### `@InVertex`
On an `@EdgeType` class: marks the field holding the in-vertex (target) of the edge.
The field type must be a `@VertexType` class.
Omitting `@InVertex` entirely = edge-only inclusion; the target vertex is not loaded.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InVertex {
}
```
---
### `@Alias`
On a `@SubgraphType` field: specifies the Gremlin `as()` alias that this field is bound
to. Defaults to the field name when omitted.
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Alias {
String value();
}
```
**Example:**
```java
@Alias("dept")
Department department; // binds to .as("dept") in the Gremlin query
```
---
## Query Annotations
---
### `@Query`
Declares a Gremlin traversal. Used on `@ClothoRepository` interface methods (primary use)
or on `@VertexType` classes as named queries (secondary use).
```java
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Queries.class) // allows multiple @Query on a class (different names)
public @interface Query {
String value() default ""; // Gremlin string (for method use)
String name() default ""; // Named query identifier (for class-level use)
String gremlin() default ""; // Gremlin string (for class-level use; alias for clarity)
boolean mapResult() default true; // false = return raw Gremlin result
}
```
**Examples:**
```java
// On a repository method
@Query("g.V().hasLabel('Employee').has('dept',:dept)")
List<Employee> findByDepartment(@Param("dept") String dept);
// Raw result — no Clotho mapping
@Query(value = "g.V().hasLabel('Employee').count()", mapResult = false)
long countAll();
// Named query on a class
@VertexType("Order")
@Query(name = "openForCustomer",
gremlin = "g.V().has('Customer','id',:custId).out('PLACED').has('status','OPEN')")
public class Order extends ClothoVertex { ... }
```
---
### `@Param`
Binds a method parameter to a named placeholder in a `@Query` Gremlin string.
```java
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
String value(); // placeholder name (without the colon)
}
```
**Example:**
```java
@Query("g.V().has('Employee','dept',:dept).has('level',:level)")
List<Employee> findByDeptAndLevel(
@Param("dept") String department,
@Param("level") int level);
```
---
## Spring Annotation
---
### `@ClothoRepository`
Marks an interface as a Clotho query interface. The `clotho-spring-boot-starter` scans for
these interfaces and registers a dynamic proxy as a Spring bean.
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClothoRepository {
}
```
**Example:**
```java
@ClothoRepository
public interface OrderQueries {
@Query("g.V().has('Order','status','OPEN')")
List<Order> findOpenOrders();
}
```
Inject via Spring as you would any repository:
```java
@Autowired OrderQueries orderQueries;
```