Skip to main content

Execute Static Methods

The Execute operation exposes static Java methods directly through GraphQL, providing a powerful extension point for custom business logic that doesn't fit the standard CRUD model of content operations. By registering methods (or whole classes of them) in your schema settings, you can create GraphQL queries and mutations that invoke your Java code, pass typed arguments, and return rich results.

Execute is ideal for calculations, integrations with external systems, batch operations, search algorithms, or any functionality beyond content retrieval and manipulation. It embodies an API-first philosophy: your Java APIs become directly accessible through GraphQL without duplicating logic in view models or custom endpoint implementations.

Configuration

Register methods per operation type—QUERY for read-only logic, MUTATION for side-effecting logic:

1
import java.util.Set;
2
3
import com.psddev.dari.db.Recordable;
4
import com.psddev.dari.db.Singleton;
5
import com.psddev.graphql.gca.GCAEndpoint;
6
import com.psddev.graphql.gca.GCASchemaSettings;
7
import com.psddev.graphql.gca.settings.OperationType;
8
9
@Recordable.DisplayName("My First GCA Endpoint")
10
public class MyFirstGCAEndpoint extends GCAEndpoint implements Singleton {
11
12
@Override
13
public Set<String> getPaths() {
14
return Set.of("/my-first-gca");
15
}
16
17
@Override
18
protected GCASchemaSettings getSchemaSettings() {
19
return GCASchemaSettings.newBuilder()
20
.mutableEntryClass(Event.class)
21
.contentActionTypesAll()
22
.entryViewClass(EventViewModel.class)
23
.staticMethods(OperationType.QUERY, EventQueries.class)
24
.build();
25
}
26
}

The full builder surface:

MethodDescription
staticMethods(OperationType, Class<?>)Registers every public static method of the class.
staticMethods(OperationType, Collection<Method>)Registers specific methods.
staticMethod(OperationType, Method)Registers one method under its own name.
staticMethod(OperationType, String alias, Method)Registers one method under a custom field name.
instanceMethod(Method) / instanceMethods(...)Attaches public instance methods to their declaring record types, appearing as extra fields on those types.

How methods map to the schema

Registered methods appear under an Execute field on the query root (for QUERY registrations) or the mutation root (for MUTATION), grouped by declaring class:

1
Execute → <DeclaringClass> → <methodName>(<parameters>): <return type>
  • Field names come from the method name (or your alias).
  • Parameters become GraphQL arguments with the corresponding scalar/object types; parameter names are preserved.
  • Return types map the same way content field types do—primitives and boxed types, strings, dates, collections, maps, and Recordable types already present in the schema. Javadoc becomes the field's documentation.

Using the EventQueries helper from Getting Started:

1
query EventQueries($location: String) {
2
Execute {
3
EventQueries {
4
getUpcomingEventsCount(location: $location)
5
}
6
}
7
}
8

As with any GraphQL field, aliases let a single request invoke the same method multiple times with different arguments:

1
{
2
Execute {
3
EventQueries {
4
reston: getUpcomingEventsCount(location: "20190")
5
dc: getUpcomingEventsCount(location: "20001")
6
}
7
}
8
}

Queries vs. mutations

The OperationType you register under is a contract with your consumers, not an enforcement mechanism—GraphQL clients, caches, and tooling assume query fields are safe to retry and cache. Register anything that writes data under MUTATION.

Methods that return Recordable types participate fully in the schema: consumers can select fields on returned records exactly as they would from a Get or Query result. Note that if your endpoint uses disallowAllStateAccess(), explicitly registered static methods are the one exception—record-returning methods you registered remain available.

Instance methods

Beyond static methods, instanceMethod(...) attaches public instance methods to their declaring content type, exposing computed values as fields on that type wherever it appears in the schema—without registering the method with the Dari type system. This is a lightweight alternative to a view model when you need one or two computed fields on a content type.

When to use Execute vs. alternatives

It is often possible to achieve the same result through the Query operation, a ViewModel, or a method accessed from Get. Some guidance:

  • Use Execute when the logic isn't anchored to a single content item, when you're wrapping an existing Java API, or when the call signature (typed args in, result out) is the natural shape.
  • Use a ViewModel when the logic is presentation for a piece of content, or you want the result to participate in the view system (preview, themes).
  • Use Query when what you really want is a filtered collection—predicates are more flexible for consumers than a hardcoded method.

Next steps

Was this page helpful?

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.