Lets a static Java method choose which jOOQ table backs a field’s SELECT. The reflected method receives the field’s GraphQL arguments (and any contextArguments:) and returns a generated jOOQ table class; the rewrite then projects Type.$fields(…) against that table exactly as if @table had named it directly. At root, this is a developer-driven equivalent of @table on a Query field; at child sites, it switches the SQL source mid-tree based on argument values.
@tableMethod is the seam for table selection that depends on argument values: returning a sharded table by tenant, picking between archived and live history tables, or resolving any catalog choice that can’t be expressed statically. The directive composes with @reference (at child sites) and with @condition (the standard predicate axis still applies on top of the chosen table).
SDL signature
directive @tableMethod(
className: String!
method: String!
argMapping: String
contextArguments: [String!]
) on FIELD_DEFINITION
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
|
|
(required) |
Fully-qualified Java class name carrying the static table method. |
|
|
(required) |
Static method name. Must return the generated jOOQ table class for the field’s |
|
|
(empty) |
Rebinds GraphQL argument names to differently-named Java parameters ( |
|
|
|
Names of values to pull from the GraphQL |
Method-signature contract
The developer’s static method receives only GraphQL field arguments and contextArguments: values. No parent table, return-type table, or other implicit Table parameter is passed; graphitron derives the target table from the method’s return type, and parent-table filtering at child sites is @reference's job.
A method declaring an org.jooq.Table<?> parameter is rejected at build time.
Canonical examples
A @table-typed root query whose backing table is chosen by argument value. The method returns the specific generated jOOQ Film class and the rewrite projects FilmType.$fields(…) against the returned table:
type Query {
popularFilms(minRentalRate: Float!): [Film!]!
@tableMethod(
className: "com.example.services.SampleQueryService",
method: "popularFilms"
)
}
public final class SampleQueryService {
public static Film popularFilms(BigDecimal minRentalRate) {
return Tables.FILM.where(Tables.FILM.RENTAL_RATE.ge(minRentalRate));
}
}
A child-site @tableMethod that swaps the source table for a single field while leaving its siblings on the parent’s @table:
type Customer @table(name: "customer") {
rentals(after: Timestamp!): [Rental!]!
@tableMethod(
className: "com.example.services.RentalService",
method: "recentRentals"
)
}
@tableMethod with contextArguments:. The reflected method receives the GraphQL argument and the named context values:
type Query {
tenantBills(month: String!): [Bill!]!
@tableMethod(
className: "com.example.services.BillService",
method: "byTenantAndMonth",
contextArguments: ["tenantId"]
)
}
byTenantAndMonth(String month, UUID tenantId) runs at request time with tenantId pulled from GraphQLContext.
Constraints
-
The field’s return type must be
@table-bound at every site (root and child). A non-@tablereturn (scalar, enum, plain@record, polymorphic) is rejected with@tableMethod requires a @table-annotated return type. The directive’s whole purpose is to bind a developer-authored jOOQ table method, which by construction returns a generated jOOQ table class; a scalar / enum return is malformed. -
At root sites,
Connection-wrapped return types are rejected:@tableMethod at the root does not support Connection return types — use [T] or T instead. Use plain[Film!]!orFilmat the field; the rewrite does not synthesise a Connection envelope around a developer-chosen table. -
The reflected method’s exact return type must equal the generated jOOQ table class for the field’s element type, not a wider
Table<R>. The strict invariant catches catalog-vs-method-signature drift at build time. -
The method must not declare an
org.jooq.Table<?>parameter. graphitron derives the target table from the return type; parent-table filtering is handled by@reference. -
className:andmethod:are both required (enforced by the schema). Reflection-time failures surface astable method could not be resolved — …. -
argMapping:rebinds GraphQL argument names to differently-named Java parameters when conventions diverge. argMapping errors surface astable method could not be resolved — @tableMethod …. -
contextArguments:values must already be wired into the runtimeGraphQLContextmap. A typo surfaces as anullparameter at request time, not as a build error. -
className:must be a fully-qualified class name reachable on the rewrite Maven plugin’s classpath (declare the carrying artifact under<dependencies>of the plugin’s<plugin>block). Reflection failures surface astable method could not be resolved — <reflection error>.
See also
-
@tableis the catalog-driven counterpart, choose@tablewhen the same jOOQ table always backs the field, choose@tableMethodwhen the table is selected at request time. -
@serviceis the alternative when the developer supplies the entire fetcher rather than just the source table. -
@conditionlayers explicit predicates on top of the chosen table, the two compose. -
@referencestill controls the join path at child sites; the chosen table is the path’s leaf. -
How-to: Wiring external Java code covers the rewrite plugin’s classpath setup shared across
@tableMethod,@externalField,@condition, and@service.