data-api-builder icon indicating copy to clipboard operation
data-api-builder copied to clipboard

[Enh]: Support wildcard entities

Open JerryNixon opened this issue 5 months ago • 1 comments

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.

{
  "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

{
  "autoentities": {
    "{definition-name}": {

      "patterns": {
        "include": "%.%", // default: null. mssql syntax (T-SQL LIKE)
        "exclude": "sales.%", // default: null. mssql syntax (T-SQL LIKE)
        "name": "{schema}{object}" // default: null. interpolation syntax (must be unique)
      },

      "template": {
        "mcp": { "dml-tool": "<boolean>" }, // default: true
        "rest": { "enabled": "<boolean>" }, // default: true
        "graphql": { "enabled": "<boolean>" }, // default: true
        "health": { "enabled": "<boolean>" }, // default: true
        "cache": {
          "enabled": "<boolean>", // default: false
          "ttl-seconds": "<integer>", // default: null
          "level": "<enum>" // default: null
        }
      },

      "permissions": [ // at least one is required
        {
          "role": "<string>",
          "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 {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 autoentities configure subcommand that operates like an upsert.

dab autoentities configure {definition-name} --patterns.include value
dab autoentities configure {definition-name} --patterns.exclude value
dab autoentities configure {definition-name} --patterns.name value

dab autoentities configure {definition-name} --template.mcp.dml-tool value
dab autoentities configure {definition-name} --template.rest.enabled value
dab autoentities configure {definition-name} --template.graphql.enabled value
dab autoentities configure {definition-name} --template.cache.enabled value
dab autoentities configure {definition-name} --template.cache.ttl-seconds value
dab autoentities configure {definition-name} --template.cache.level value
dab autoentities configure {definition-name} --template.health.enabled value

dab autoentities configure {definition-name} --permissions role:actions

CLI Behavior

  • The autoentities configure 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

"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 {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
  }
}

JerryNixon avatar Jul 30 '25 22:07 JerryNixon

This work item spans over November and December months.

souvikghosh04 avatar Oct 27 '25 16:10 souvikghosh04