Operation
ActiveQL does provide per convention standard queries and mutations based on your entities. We think that this is often the easiest way to interact with your domain graph. Some might consider generic CRUD queries and mutations an anti-pattern though; see e.g.: https://xuorig.medium.com/graphql-mutation-design-anemic-mutations-dd107ba70496 (opens in a new tab)
We find both approaches in nearly every application useful. You often have a number of quite simple entities with relations to each other (often so called basic data) and it should be a simple as possible to offer CRUD operations to these entities. On the other hand you have non-trivial business requirements. So, when it comes to complex business logic we strongly recommend to implement custom queries and mutations - or even better to use operations.
An operation will be compiled into a mutation with
- input in which you express
- multiple types and attributes that may or may not be referencing existing entities
- dedicated dynamic validation logic specific for the input of this operation
- return that includes
- attribute dispositions - this is the current state of input requirements
- validation violations
- the actual result - that can be an Entity item or custom type
- default or custom logic for
- evaluating the attribute dispositions
- validating the operation input (per default against the dispositions)
- making 3rd party API calls
- executing any custom code
- saving any data from the input (via entities) to the data store in a single transaction
- determine the result value
Operations are a great way to express business logic that is defined one level "above" a DomainConfiguration. In ActiveInsurance e.g. you define products that result in complex Quote, Application or Policy mutations. Rather than a business user having to define operations these are generated from the product configuration.
Input
Usually the most complex part of an operation configuration is the input configuration. Here you define how the mutation or API call appears to a client and how it's input is validated.
In an operation you can define the input based on entities or with arbitrary types and attributes. And you can assign dynamic configuration to it's behavior.
ValidationViolations
Just like entity mutations an operation returns a list of violated validations in the response to a client. The path property of a ValidationViolation corresponds to the value in the operation's input. The message is human readable.
Input dispositions
Since some of the configuration is dynamic, a client might not know from the API documentation what an operation mutation would expect an operation input to be valid. For this a client can request the InputDispositions from an operation mutation to get the actual state of any attribute validation.
For detailed documentation see Input dispositions