Use generated page CRUD APIs for normal dynamic entity pages. Custom endpoints are an advanced option for exposing small model-owned REST APIs that do not map to standard list, get, create, update, delete, export, file, or attachment operations.
Custom endpoints are defined in `model.json` or through the Low-Code Designer. Each endpoint executes server-side JavaScript and is registered as an ASP.NET Core route.
Custom endpoints are defined in JSON descriptor files or through the Low-Code Designer. Each endpoint executes server-side JavaScript and is registered as an ASP.NET Core route.
## Defining Endpoints
@ -234,4 +234,4 @@ Default blocked headers also include hop-by-hop headers such as `Connection`, `T
> **Preview:** The Low-Code Designer is part of the preview Low-Code System. Designer screens, metadata fields, and validation rules may change before general availability.
The Low-Code Designer is available in ABP Admin Console. It is the main UI for building and maintaining low-code models.
The Low-Code Designer is available in ABP Admin Console. It is the main UI for building and maintaining low-code descriptor metadata.
```text
/admin-console/lowcode-designer
```
The designer works with layered model metadata. In development, generated projects include a `_Dynamic/model.json` file and a generated initializer. The designer can also persist changes to the database JSON layer, depending on the selected layer and permissions.
The designer works with layered descriptor metadata. In development, generated projects include source-controlled descriptor files under `_Dynamic` and a generated initializer. The designer can also persist changes to the database JSON layer, depending on the selected layer and permissions.
@ -120,7 +120,7 @@ Generated pages and menus are permission-aware. If a user cannot access a page,
## Actions and Scripts
Use **Actions** only when model metadata and standard CRUD behavior are not enough. The scripting surface can define custom HTTP endpoints, distributed event handlers, background jobs, and scheduled background workers. Scripts run server-side and use the [Scripting API](scripting-api.md).
Use **Actions** only when descriptor metadata and standard CRUD behavior are not enough. The scripting surface can define custom HTTP endpoints, distributed event handlers, background jobs, and scheduled background workers. Scripts run server-side and use the [Scripting API](scripting-api.md).
JavaScript editors in the Designer provide syntax highlighting, service autocomplete, entity name autocomplete, entity property autocomplete, enum autocomplete, and an **Available context** list. The context list reflects the services enabled for the selected script type. The `fileFields` and `imageFields` context items are selector trees for `File` and `Image` properties used by the file and image helpers; they are not lists of every entity property.
@ -132,4 +132,4 @@ Use **Health** before shipping changes. It helps catch missing display propertie
## Source Control
For source-controlled models, keep `_Dynamic/model.json` and the generated initializer in your application repository. Use [model.json Structure](model-json.md), [Attributes & Fluent API](fluent-api.md), and [Reference Entities](reference-entities.md) for advanced editing and integration details.
For source-controlled models, keep the `_Dynamic` descriptor files and the generated initializer in your application repository. Use [Model Descriptor Files](model-json.md), [Attributes & Fluent API](fluent-api.md), and [Reference Entities](reference-entities.md) for advanced editing and integration details.
For example, if an attribute sets `[DynamicPropertyUnique]` and model.json sets `"isUnique": false`, the JSON value wins because JSON layer has higher priority than Code layer.
For example, if an attribute sets `[DynamicPropertyUnique]` and a descriptor sets `"isUnique": false`, the JSON value wins because the JSON descriptor layer has higher priority than the Code layer.
## End-to-End Example
@ -570,6 +570,6 @@ This gives you four auto-generated pages (Customers, Products, Orders with neste
The designer stores and reads the same model metadata described in the reference pages below. Use these pages when you need source-controlled model files, custom startup wiring, script handlers, or low-level integration details.
The designer stores and reads the same descriptor metadata described in the reference pages below. Use these pages when you need source-controlled descriptor files, custom startup wiring, script handlers, or low-level integration details.
| Topic | Use it for |
|-------|------------|
| [Designer](designer.md) | Admin Console tabs, entity/page/form setup, permissions, and health |
| [React Runtime](react-runtime.md) | React package wiring, routes, menu items, filters, forms, and export |
> **Preview:** Interceptors and their JavaScript context are preview extension points. Script context members, validation behavior, and lifecycle hooks may change before general availability.
Use designer actions and model metadata for standard low-code behavior first. Interceptors are an advanced extension point for adding JavaScript lifecycle logic when the generated CRUD flow needs validation, transformation, or replacement behavior.
Use designer actions and descriptor metadata for standard low-code behavior first. Interceptors are an advanced extension point for adding JavaScript lifecycle logic when the generated CRUD flow needs validation, transformation, or replacement behavior.
Interceptors allow you to run custom JavaScript code before, after, or instead of Create, Update, and Delete operations on dynamic entities.
@ -27,7 +27,7 @@ Interceptors allow you to run custom JavaScript code before, after, or instead o
"Description": "Define ABP Low-Code descriptor metadata and descriptor schemas for dynamic entities, pages, forms, filters, permissions, script endpoints, event handlers, background jobs, and workers."
}
```
# model.json Structure
# Model Descriptor Files
> **Preview:** The Low-Code System is currently in preview. The descriptor format is stable enough for evaluation and source control, but fields may change before general availability.
`model.json` is the source-controlled descriptor format used by the Low-Code Designer and React runtime. Use the [Low-Code Designer](designer.md) for normal editing. Use this page when you need to review, generate, merge, or source-control the JSON metadata directly.
Low-code metadata is source-controlled as JSON descriptor files used by the Low-Code Designer and React runtime. Current generated projects keep descriptors as split files under `_Dynamic`; older projects may still contain an aggregate `_Dynamic/model.json` document. Use the [Low-Code Designer](designer.md) for normal editing. Use this page when you need to review, generate, merge, or source-control the JSON metadata directly.
## File Location
Generated low-code applications keep the model file in a `_Dynamic` folder under the application domain project:
Generated low-code applications keep descriptor files in a `_Dynamic` folder under the application domain project. A typical project stores one JSON file per descriptor:
```text
YourApp.Domain/
`-- _Dynamic/
`-- model.json
|-- entities/
| `-- Acme.Campaigns.Campaign.json
|-- pages/
| `-- campaigns.json
|-- forms/
| `-- campaign-form.json
`-- permissions/
`-- Acme.Campaigns.json
```
The low-code module discovers this file during application startup. A JSON Schema (`model.schema.json`) is available in the module source and can be referenced with `$schema` for IDE IntelliSense.
Exact folders and file names are generated by the tooling for the descriptor type. Keep the whole `_Dynamic` folder and the generated initializer in source control. The low-code module discovers the descriptor metadata during application startup.
## JSON Schemas
ABP publishes JSON Schema definitions for the descriptor objects that make up low-code metadata. These schemas are useful when you generate descriptors, review changes in source control, or want IDE validation for split descriptor files.
The schema files live in the ABP repository under `schemas/low-code`. Use the branch or tag that matches your ABP version.
Use the descriptor schema directly when a descriptor is stored as its own JSON file. The descriptor object is the same shape used for one item inside the related descriptor collection.
For example, a file that stores one page descriptor can reference `page-descriptor.schema.json`, and a file that stores one form descriptor can reference `form-descriptor.schema.json`.
The published schemas validate individual descriptor objects, not an aggregate descriptor document. If you still maintain an aggregate `_Dynamic/model.json`, do not point it at `entity-descriptor.schema.json`, `page-descriptor.schema.json`, or another descriptor schema; those schemas expect one descriptor object, not the top-level arrays. For aggregate metadata, use the manifest table above as the section-level reference and validate each array item with its matching descriptor schema.
## Top-Level Sections
The current model format is page/form centered. Entities define data shape; pages and forms define the React runtime UI.
When descriptor metadata is viewed as an aggregate document, the logical sections are page/form centered. Entities define data shape; pages and forms define the React runtime UI.
```json
{
"$schema": "...",
"enums": [],
"entities": [],
"endpoints": [],
@ -431,6 +476,8 @@ Background workers require either `period` in milliseconds or `cronExpression`.
## Complete Example
The complete example below shows the logical aggregate shape. Split projects store each descriptor as its own file, but field shapes are the same.
@ -17,7 +17,7 @@ Reference Entities allow you to create foreign key relationships from **dynamic
| | Dynamic Entities | Reference Entities |
|---|-----------------|-------------------|
| **Definition** | Defined via `[DynamicEntity]` attribute or `model.json` | Existing C# classes (e.g., `IdentityUser`, `Tenant`) |
| **Definition** | Defined via `[DynamicEntity]` attribute or JSON descriptor files | Existing C# classes (e.g., `IdentityUser`, `Tenant`) |
| **CRUD Operations** | Full CRUD (Create, Read, Update, Delete) | **Read-only** — no create/update/delete |
| **UI Pages** | Auto-generated pages with data grids and forms | No UI pages |
| **Permissions** | Auto-generated permissions | No permissions |
@ -26,7 +26,7 @@ Reference Entities allow you to create foreign key relationships from **dynamic
## Overview
Dynamic entities defined via [Attributes](fluent-api.md) or [model.json](model-json.md) can reference **other dynamic entities** using foreign keys. However, you may also need to link to entities that exist **outside** the Low-Code System — such as ABP's `IdentityUser`, `Tenant`, or your own C# entity classes.
Dynamic entities defined via [Attributes](fluent-api.md) or [JSON descriptor files](model-json.md) can reference **other dynamic entities** using foreign keys. However, you may also need to link to entities that exist **outside** the Low-Code System — such as ABP's `IdentityUser`, `Tenant`, or your own C# entity classes.
**Reference entities** make this possible by exposing existing entities for:
@ -80,7 +80,7 @@ public void Add<TEntity>(
> The entity type must implement `IEntity<Guid>`.
## Using Reference Entities in model.json
## Using Reference Entities in JSON Descriptors
Reference a registered entity in a foreign key definition:
> **Preview:** Script actions are part of the preview Low-Code System. Descriptor fields, designer screens, and script context members may change before general availability.
Use **Actions** in the Low-Code Designer when model metadata and generated CRUD behavior are not enough. Actions can add JavaScript-backed HTTP endpoints, distributed event handlers, background jobs, and scheduled background workers.
Use **Actions** in the Low-Code Designer when descriptor metadata and generated CRUD behavior are not enough. Actions can add JavaScript-backed HTTP endpoints, distributed event handlers, background jobs, and scheduled background workers.
Custom HTTP endpoints are documented separately in [Custom Endpoints](custom-endpoints.md). This page focuses on the shared action designer experience and the event handler, background job, and background worker action types.
@ -256,4 +256,4 @@ The endpoint dry-run still evaluates the endpoint authentication and permission
Event handlers, background jobs, and background workers are configured in the Designer **Actions** section or in `model.json`. See [Script Actions](script-actions.md) for descriptors, examples, and dry-run testing.
Event handlers, background jobs, and background workers are configured in the Designer **Actions** section or in JSON descriptor files. See [Script Actions](script-actions.md) for descriptors, examples, and dry-run testing.