DomainGraph
Any DomainConfiguration, whether it comes from a YAML/JSON file or a DomainConfiguration object is resolved and merged into one DomainGraph ActiveQL executes a DomainGraph in form of a GraphQL schema and resolvers, with all validation and business logic. This is based on the configuration of your business domain, by large parts entities with its attributes in addition to custom queries and mutations.
DomainConfiguration
By design nearly all configuration properties are optional, since you can split them between many source. In the following any mandatory options are marked as bold.
When it comes to type of values we are using the following the notation:
| Type | YAML | JSON | Javascript / Typescript |
|---|---|---|---|
string | brand: BMW | { "brand": "BMW"} | { power: 'BMW' } |
string[] | brand: - BMW - Porsche | { "brand": ["BMW", "Porsche"]} | { power: ["BMW", "Porsche"] } |
number | power: 100 | { "power": 100} | { power: 100 } |
number[] | power: - 100 - 200 | { "power": [100, 200]} | { power: [100, 200] } |
boolean | valid: true | { "valid": true} | { valid: true } |
Overview
| Config | Type | Description |
|---|---|---|
| entity | map of EntityConfig | any thing in your business domain, think of node in graph, class in UML or table in database |
| enum | map of EnumConfig | a collection of values to restrict possible values of fields or attributes |
| query | map of QueryMutationConfig | implementations of custom queries |
| mutation | map of QueryMutationConfig | implementations of custom mutations |
| subscription | map of SubscriptionConfig | implementations of a custom subscriptions |
| type | map of TypeConfig | configuration of a GraphQL type that is not itself an entity |
| action | map of ActionConfig | implementation of a scheduled action that runs by the timer |
| operation | map of OperationConfig | complex business logic mutation |
| decisionTable | map of DtConfig | configuration of a decision table based on the DMN standard |
| restCall | map of RestCallConfig | configuration of a rest call to a 3rd party API |
| indications | string[] | attribute names that should be used (besided the standard names) to guess the indication attribute for an entity |
| now | string | Date | () => Date | callback to determine the current DateTime; default () => Date.now() |
| round | (number:number) => number | callback to round numbers; default: (number) => Math.round(number) |
| init | (runtime:Runtime) => void|Promise<void> | callback after initialization of the Runtime |
| extendSchema | (runtime:Runtime) => void | callback that is called before the schema is actually created, so you can add or manage the GraphQL schema that is about to be created |
| contextFn | {req:IncomingMessage, res:ServerResponse}, context:ResolverContext) => void|Promise<void> | callback at context creation, you could set a principal for authentication here |
| fakerGuesses | FakerGuess[] | For seeding entities. You can add default faker calls for entity attributes that are used when no seed configuration was provided |
DomainConfiguration YAML vs JSON vs Object
You can write your DomainConfiguration either as YAML, JSON or Object. The following examples would all result in exactly the same DomainGraph.
entity:
Car:
attributes:
brand: String!
color: String{
"Car": {
"attributes": {
"brand": "String!",
"color": "String"
}
}
}const domainConfiguration:DomainConfiguration = {
Car: {
attributes: {
brand: "String!",
color: "String"
}
}
}Obviously if you want to add a callback, hook or any kind of code to your DomainGraph you have to add them to a DomainConfiguration object.
const domainConfiguration:DomainConfiguration = {
entity: {
Car: {
attributes: {
brand: "String!",
color: {
type: "String",
resolve: ({item}) => {
return item.brand === 'Trabbi' ? 'himmelblau' : item.color
}
}
}
}
}
}We recommend to keep any non-code configuration in YAML files, since these are best suited to understood by non-technical people and are perfect for versioning.
All DomainConfiguration is merged in on DomainGraph so it is perfectly fine to separate any configuration over different files and/or objects. Take this two configurations:
entity:
Car:
attributes:
brand: String! const domainConfiguration:DomainConfiguration = {
entity: {
Car: {
attributes: {
color: {
type: "String",
resolve: ({item}) => {
return item.brand === 'Trabbi' ? 'himmelblau' : item.color
}
}
}
}
}
}Although we've split the AttributeConfig of the EntityConfig the DomainGraph would have one "Car" EntityConfig with both attributes "brand" and "color".
now
| Config | Description |
|---|---|
string | now will always result to the Date parsed from this string - makes only sense for tests or batch-runs |
Date | now will always result to this Date - makes only sense for tests or batch-runs |
() => Date | callback will used to determine the current DateTime |