v3/rfcs/open-dd-boolean-expression-types.md
All mutations in NDC are implemented as standalone procedures, whose semantics are opaque to OpenDD. In order to provide the ability to filter rows on which a procedure would apply, NDC is introducing boolean expression types as procedure arguments. Consequently, we would also need to support boolean expressions as arguments in OpenDD. Since OpenDD already uses boolean expressions (called filter expressions) for filtering models as a part of select many, we would want to unify the two definitions.
The first proposal is to introduce a new OpenDD object type for filter expressions. This will allow us to exact;u define filter expressions and reuse them across models and command arguments.
kind: ObjectFilterExpressionType
version: v1
definition:
name: AuthorFilterExpression
objectType: Author
dataConnectorName: my_db
dataConnectorObjectType: author
filterableFields:
- fieldName: id
comparisonExpression:
operators:
enableAll: true
- fieldName: name
comparisonExpression:
operators:
enableSpecific: ["_eq", "_like"]
graphql:
typeName: Author_bool_exp
Currently type mappings are specified as a part of model / command source, where
we define how the object types used in a particular model map to object types
used in the source data connector. It was designed this way so that
kind: ObjectType was defined purely in terms of OpenDD and coupling to a
connector was done only in kind: Model / kind: Command. However, now that
mutations will be opaque commands, we expect an ObjectType used within a model
to be commonly reused across multiple commands, making it verbose to redefine
the type mappings for every command.
Hence, the second proposal is to move type mappings as a part of
kind: ObjectType and removed from kind: Model / kind: Command. This is
also more intuitive to understand for a reader of OpenDD.
kind: ObjectType
version: v1
definition:
name: Author
fields:
- name: id
type: Int!
- name: name
type: String
dataConnectorTypeMapping: # Optional key
- dataConnectorName: my_db
dataConnectorObjectType: author
fieldMapping:
id:
column: author_id
name:
column: author_name
Since filter expressions and type mappings are now being defined elsewhere,
updates are needed to kind: Model.
typeMappings key from the source field of the model definition.filterExpressionType key from the graphql field of the model
definition.filterable_fields key from the model definition.filterExpressionType key to the model definition, which is
optional and points to an existing ObjectFilterExpressionType that is
defined on the same object type as the model's object type.kind: Model
version: v1
definition:
name: Authors
objectType: Author
filterExpressionType: AuthorFilterExpression
orderableFields: ...
graphql:
orderByExpressionType: Author_order_by
selectMany:
queryRootField: authors
source:
dataConnectorName: author
Similarly, we would remove typeMappings key from the source field of the
command definition.
A couple of alternatives were considered, but rejected.
kind: Command
version: v1
definition:
arguments:
- name: where
type:
booleanExpression:
objectType: Author
filterableFields: ...
graphql:
typeName: Author_bool_exp
There would be too much repition and it would be the inconsistent with the rest of OpenDD where you can only refer to explicitly defined types.
kind: ObjectType
version: v1
definition:
name: Author
fields: ...
filterExpressions:
name: AuthorFilterExpression
dataConnectorName: my_db
dataConnectorObjectType: author
filterableFields: ...
graphql:
typeName: Author_bool_exp
The problem with this is it is unclear whether the name AuthorFilterExpression
shares the same namespace with other OpenDD types.
- name: id
type:
regular: Int!
- name: where
type:
booleanExpression: AuthorFilterExpression