Azure / Azure/data-api-builder
[Enh]: Support autoentities
- Dominant language
- C#
- Stars
- 1.5k
- Forks
- 370
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 8
Description
## What
Add entities automatically.
## Why
Super-simplify setup and onboarding.
> [!Note]
> Autoentities cannot conflict with explicit entities.
## Constraints
* Data-source type: `MSSQL`-only
* Object-source type: `Table`-only
* When at least one `autoentities` member is present, the top-level `entities` section becomes optional.
## How
Add new top-level section to the configuration.
```jsonc
{
"runtime": {},
"entities": {},
"autoentities": {} // new
}
```
This defines the search pattern as well as the entity defaults.
> [!Important]
> Autoentities are in-memory only. The configuration file is never updated from this behavior.
### Configuration
```jsonc
{
"autoentities": {
"{definition-name}": {
"patterns": {
"include": [ "t1", "t2", "t3", "%.%" ], // default: null which means all. mssql syntax (T-SQL LIKE)
"exclude": [ "t3" ], // default: null which means none. mssql syntax (T-SQL LIKE)
"name": "{schema}{object}" // default: null which means "{schema}_{object}". This is interpolation syntax
}
"template": {
"mcp": { "dml-tool": "" }, // default: true
"rest": { "enabled": "" }, // default: true
"graphql": { "enabled": "" }, // default: true
"health": { "enabled": "" }, // default: true
"cache": {
"enabled": "", // default: false
"ttl-seconds": "", // default: 5
"level": "" // default: L1L2
}
},
"permissions": [ // at least one is required
{
"role": "",
"actions": [
"*",
"create",
"read",
"update",
"delete"
]
}
]
}
}
}
```
## Behavior
### Definition and Patterns
* `{definition-name}` uniquely identifies a definition in `autoentities`, used by the CLI for upserts.
* `patterns.include`: `null` includes all (default). Uses MSSQL `LIKE` syntax validated at runtime.
* `patterns.exclude`: `null` excludes none (default). Uses MSSQL `LIKE` syntax validated at runtime.
* `patterns.name`: `null` equals `{schema}_{object}` (default). Supports `{schema}` and `{object}` interpolation (for example `{schema}{object}`) and must be unique.
* The `patterns` section is optional and uses defaults when omitted.
* When an entity matches both include and exclude, exclude wins.
### Template and Permissions
* The `template` section is optional and uses defaults when omitted.
* Defaults in `template` match defaults in `entities`.
* The `permissions` section is required and must contain at least one member.
* Some properties are inferred from entity names (for example, `graphql.type.singular`, `graphql.type.plural`, and `rest.path`), and duplicates of existing definitions are invalid.
### Execution Rules
* Autoentities supports only MSSQL tables.
* Default exclusions: schemas `sys`, `INFORMATION_SCHEMA`, table `__EFMigrationsHistory`, and any table with `is_shipped = 1`.
* Autoentities runs at startup (`dab start`) and on Hot Reload of `autoentities`; it does not re-run when the database schema changes.
* Generated entities exist only in memory; the configuration file is never updated.
* Each generated entity tracks its parent `{definition-name}`.
* Each `autoentities` definition executes independently and sequentially.
### Validation and Errors
* Startup stops if an autoentities entity name duplicates one from `entities` or another autoentities definition.
* Autoentities fails if resulting `{entity-name}` values are not unique or if no permissions are defined.
* Autoentities continues gracefully if filters yield zero entities.
* `include` and `exclude` patterns follow MSSQL `LIKE` syntax and are validated only by the database at runtime.
## Command line
Introduce a new `auto-config` subcommand that operates like an upsert.
```sh
dab auto-config {definition-name} --patterns.include value
dab auto-config {definition-name} --patterns.exclude value
dab auto-config {definition-name} --patterns.name value
dab auto-config {definition-name} --template.mcp.dml-tool value
dab auto-config {definition-name} --template.rest.enabled value
dab auto-config {definition-name} --template.graphql.enabled value
dab auto-config {definition-name} --template.cache.enabled value
dab auto-config {definition-name} --template.cache.ttl-seconds value
dab auto-config {definition-name} --template.cache.level value
dab auto-config {definition-name} --template.health.enabled value
dab auto-config {definition-name} --permissions role:actions
dab auto-config-simulate --output file.json
```
### CLI Behavior
* The `auto-config` subcommand operates like an upsert.
* It creates the `autoentities` section if missing.
* It creates the `{definition-name}` section if missing.
* When the literal string `null` is passed as a value, the value is set to `null`.
There is currently no way to remove a property through the CLI.
## Health & Logging
### Health Endpoint
Include in the endpoint tag: `"autoentities-definition: {definition-name}"` for autoentities; otherwise omit from health JSON output.
### Log Information
`{definition-name}` created `{entity-name}` for `{schema}.{object}` as (1 of 10).
### Log Warning
`{definition-name}` resulted in zero entities.
### Log Error
`{definition-name}` failed. `{entity-name}` for `{schema}.{object}` is not unique.
`{definition-name}` failed. `{entity-name}` for `{schema}.{object}` has no primary keys.
`{definition-name}` failed. `{entity-name}` for `{schema}.{object}` has invalid data types.
## Suggested Tests
Rename `AutogenQueryTests` to `AutoentitiesQueryTests`.
## Suggested JSON Schema Update
```json
"autoentities": {
"type": "object",
"description": "Defines automatic entity generation rules for MSSQL tables based on include/exclude patterns and defaults.",
"if": {
"not": {
"properties": {
"data-source": {
"properties": {
"database-type": { "const": "mssql" }
}
}
}
}
},
"then": {
"errorMessage": "Autoentities require the data-source.database-type to be 'mssql'."
},
"allOf": [
{
"if": {
"not": {
"required": ["entities"]
}
},
"then": {
"properties": {
"autoentities": {
"minProperties": 1
}
},
"errorMessage": "The 'entities' section is optional only when at least one autoentities definition exists."
}
}
],
"additionalProperties": {
"type": "object",
"properties": {
"patterns": {
"type": "object",
"properties": {
"include": {
"type": ["string", "null"],
"description": "MSSQL LIKE pattern for objects to include. Null includes all."
},
"exclude": {
"type": ["string", "null"],
"description": "MSSQL LIKE pattern for objects to exclude. Null excludes none."
},
"name": {
"type": ["string", "null"],
"description": "Entity name interpolation pattern using {schema} and {object}. Null defaults to {schema}_{object}."
}
},
"additionalProperties": false
},
"template": {
"type": "object",
"properties": {
"mcp": {
"type": "object",
"properties": {
"dml-tool": { "type": "boolean", "default": true }
},
"additionalProperties": false
},
"rest": {
"type": "object",
"properties": {
"enabled": { "type": "boolean", "default": true }
},
"additionalProperties": false
},
"graphql": {
"type": "object",
"properties": {
"enabled": { "type": "boolean", "default": true }
},
"additionalProperties": false
},
"health": {
"type": "object",
"properties": {
"enabled": { "type": "boolean", "default": true }
},
"additionalProperties": false
},
"cache": {
"type": "object",
"properties": {
"enabled": { "type": "boolean", "default": false },
"ttl-seconds": { "type": ["integer", "null"] },
"level": {
"type": ["string", "null"],
"enum": ["entity", "record", null]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"permissions": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["role", "actions"],
"properties": {
"role": { "type": "string" },
"actions": {
"type": "array",
"items": {
"type": "string",
"enum": ["*", "create", "read", "update", "delete"]
},
"minItems": 1
}
},
"additionalProperties": false
}
}
},
"required": ["permissions"],
"additionalProperties": false
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.