Domain configuration
Overview

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:

TypeYAMLJSONJavascript / Typescript
stringbrand: BMW{ "brand": "BMW"}{ power: 'BMW' }
string[]brand:
   - BMW
   - Porsche
{ "brand": ["BMW", "Porsche"]}{ power: ["BMW", "Porsche"] }
numberpower: 100{ "power": 100}{ power: 100 }
number[]power:
   - 100
   - 200
{ "power": [100, 200]}{ power: [100, 200] }
booleanvalid: true{ "valid": true}{ valid: true }

Overview

ConfigTypeDescription
entitymap of EntityConfigany thing in your business domain, think of node in graph, class in UML or table in database
enummap of EnumConfiga collection of values to restrict possible values of fields or attributes
querymap of QueryMutationConfigimplementations of custom queries
mutationmap of QueryMutationConfigimplementations of custom mutations
subscriptionmap of SubscriptionConfigimplementations of a custom subscriptions
typemap of TypeConfigconfiguration of a GraphQL type that is not itself an entity
actionmap of ActionConfigimplementation of a scheduled action that runs by the timer
operationmap of OperationConfigcomplex business logic mutation
decisionTablemap of DtConfigconfiguration of a decision table based on the DMN standard
restCallmap of RestCallConfigconfiguration of a rest call to a 3rd party API
indicationsstring[]attribute names that should be used (besided the standard names) to guess the indication attribute for an entity
nowstring | Date | () => Datecallback to determine the current DateTime; default () => Date.now()
round(number:number) => numbercallback to round numbers; default: (number) => Math.round(number)
init(runtime:Runtime) => void|Promise<void>callback after initialization of the Runtime
extendSchema(runtime:Runtime) => voidcallback 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
fakerGuessesFakerGuess[]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

ConfigDescription
stringnow will always result to the Date parsed from this string - makes only sense for tests or batch-runs
Datenow will always result to this Date - makes only sense for tests or batch-runs
() => Datecallback will used to determine the current DateTime