Skip to content

Load collections with requests ​

Русская версия

Requests connect a panel to object data. Choose the strategy from the data relationship, not from the visual panel: a Table may load a MetaType collection, linked objects, a method result, or a custom HTTP response, while a dependent detail surface may load one event-selected object.

This guide covers the shared runtime request router. A variant can expose a narrower local type or add its own request behavior, so confirm the variant guide before copying a request into another panel.

Decide which strategy to use ​

User problemRequired discriminatorRuntime strategyQuery ownership
List objects of one MetaTypemetaTypeNamestandard object searchserver
List objects reached through a linkgetSelectedObjectForEventId + linkName, without metaTypeNamelinked objectsserver
List objects whose attribute points to the selectionmetaTypeName + event ID + linkedAttributelinked-attribute searchserver
Load one known or selected objectan ObjectSelector supplied by the consumersingle objectserver
Run a MetaMethod as the data sourcemethodNamemethodmethod response
Adapt arbitrary JSON rowscustomRequestcustom HTTPclient pagination and sorting

All selected-object strategies require a prior panel event that stores an object selector with addSelectedObjectToRequest.

Strategy precedence ​

When several discriminator fields appear together, the shared router chooses the first matching strategy:

  1. customRequest
  2. methodName
  3. consumer-supplied single objectSelector
  4. metaTypeName + selected event + linkedAttribute
  5. selected event + linkName without metaTypeName
  6. metaTypeName

This precedence is a compatibility rule, not a configuration technique. Keep one clear discriminator set per request. A customRequest silently wins over an accidentally retained metaTypeName, and a method request wins over both linked and standard fields.

Projection and attribute paths ​

For standard and linked requests, the object projection is chosen in this order:

  1. an explicit projection supplied by the calling consumer;
  2. request.attributeList;
  3. the panel's direct column attributes.

The router deduplicates paths and converts nested dots to the API pipe format. For linked-object requests, link.quantity becomes link:quantity; link attributes are excluded from a standard object projection. Filters, sorts, and editor fields do not automatically enlarge a Table projection.

Custom requests do not use the object projection. Their returned row keys are adapted to attributes and optional column dataType metadata.

Standard request ​

Use a standard request for an independently queryable MetaType.

json
{
  "request": {
    "metaTypeName": "ProductionOrder",
    "attributeList": ["code", "status", "product.name"],
    "findAttributes": [
      {
        "field": "status",
        "compareType": "EQUAL",
        "value": "released"
      }
    ],
    "sortParams": [
      { "attribute": "code", "sortDirection": "ASC" }
    ]
  },
  "pagination": {
    "rowsPerPage": [10, 25, 50]
  }
}

The first rowsPerPage value is the initial page limit. The response pagination becomes the rendered total, limit, and offset.

Linked requests ​

Use linkName when the backend relationship itself defines the collection. The selected parent comes from the event.

json
{
  "request": {
    "getSelectedObjectForEventId": "order-selected",
    "linkName": "OrderOperation",
    "reverse": false,
    "attributeList": ["code", "status", "link.sequence"]
  }
}

reverse is false unless explicitly true. Filters and sorts for obj and link fields receive endpoint-specific prefixes during transport serialization.

Linked attribute ​

Use linkedAttribute when the child MetaType stores a reference attribute instead of being loaded through getLinkedObjects.

json
{
  "request": {
    "metaTypeName": "Operation",
    "getSelectedObjectForEventId": "order-selected",
    "linkedAttribute": "order"
  }
}

The runtime appends an equality filter for linkedAttribute and the selected object GUID. Table also sends its current applied findAttributes. Clearing those filters with Reset followed by Apply does not remove this required parent filter.

Select a parent in the source panel to start this request. Until the configured selection event contains a parent, Table sends no POST /Object/find for this linked-attribute request. Deselecting the parent clears the child rows while preserving the applied user filters. Selecting a parent again uses that selection and the same applied filters.

Method request ​

A method source uses the same object-endpoint model as runMethod actions.

json
{
  "id": "local-shared-config-method-request",
  "type": "table",
  "request": {
    "methodName": "FindLocalOrdersForAnchor",
    "parent": "LocalOrder",
    "objects": [
      {
        "objectId": {
          "objectGuid": "local-order-001"
        }
      }
    ]
  },
  "columns": [
    { "attribute": "code", "label": "Code" },
    { "attribute": "product", "label": "Product" },
    { "attribute": "status", "label": "Status" },
    { "attribute": "priority", "label": "Priority" }
  ]
}

The method response is treated as an object collection. Current Table runtime supports this route through the shared router even though older Table-local request declarations and prose omit it. The shared endpoint resolver turns the configured objectId into the GUID sent in objects; the runtime then posts parent, methodName, that GUID array, and an empty params object to /MetaMethods/Run. Filters, sorting, and pagination are not applied by the method executor itself; the method contract must return the usable result.

The checked-in local handler recognizes this fixture-only method and requires the matching LocalOrder parent plus the local-order-001 anchor. It returns the shared three-row local-order dataset in ObjectsResponse shape. This is proof of the real frontend execution path, not a production method-name claim.

Open the Method request tab and load Table rows through MetaMethods/Run

Custom HTTP request ​

Use a custom request only when the endpoint returns rows that are not available through the standard object APIs.

json
{
  "request": {
    "customRequest": {
      "method": "GET",
      "url": "/reports/order-progress",
      "idField": "orderId",
      "dataPath": "data.rows"
    }
  },
  "pagination": {
    "rowsPerPage": [10, 25]
  },
  "columns": [
    { "attribute": "orderId", "label": "Order", "dataType": "Guid" },
    { "attribute": "progress", "label": "Progress", "dataType": "Double" }
  ]
}

The current executor fetches the configured URL and method, extracts the array at dataPath when provided, then sorts and paginates the raw array in the client. idField defaults to id; the transformer converts that field to the row's id, objectGuid, and objectSelector.objectGuid. The field must therefore be present and unique across the complete response when row identity matters. A matching column dataType takes precedence; otherwise the runtime infers a type from the returned value.

The checked-in shared-config fixture exercises a concrete custom response:

json
{
  "id": "local-shared-config-custom-request",
  "type": "table",
  "request": {
    "customRequest": {
      "method": "GET",
      "url": "/applications/local-panel-fixtures/json-data",
      "dataPath": "panel.panels",
      "idField": "type"
    }
  },
  "pagination": { "rowsPerPage": [1, 2] },
  "columns": [
    {
      "attribute": "id",
      "dataType": "String",
      "label": "Panel ID",
      "sortable": true
    },
    {
      "attribute": "type",
      "dataType": "String",
      "label": "Type",
      "sortable": true
    },
    {
      "attribute": "panelLayout",
      "dataType": "Json",
      "label": "Size settings"
    }
  ]
}

The local endpoint returns the base fixture application's JSON envelope. panel.panels is a real two-row array, and its message and table values make type a non-default unique row identifier for this fixture. Page sizes 1 and 2 and the sortable id/type columns exercise the client-side controls. The current custom executor sends only the configured URL and method; do not add request body or header examples to this journey.

Open the Custom request tab with nested extraction, typed rows, sorting, and client pagination

Filters ​

Use request.findAttributes to give Table editable initial server filters. Before Table's first object query, the application copies these entries into that panel's request state in the panel-response registry. The query reads this state and serializes it for the object API. You do not need to open or apply the filter dialog first. The application does not change the source configuration.

Configure an initial filter ​

This complete Table fragment starts with isTemplate equal to the string "true". This example uses the Operation type. Confirm that your backend exposes Operation.isTemplate; use your actual type and column names if they differ.

json
{
  "id": "templates",
  "type": "table",
  "request": {
    "metaTypeName": "Operation",
    "findAttributes": [
      { "field": "isTemplate", "compareType": "EQUAL", "value": "true" }
    ]
  },
  "filter": {
    "fields": [{ "attribute": "isTemplate", "label": "Template" }]
  },
  "columns": [{ "attribute": "isTemplate", "label": "Template" }]
}

When you open this Table, its first POST /Object/find body contains findAttributes: [{ "field": "isTemplate", "compareType": "EQUAL", "value": "true" }]. After the API responds, Table shows the returned matching rows. To verify the configuration, inspect that first request in the browser's Network panel.

Each request.findAttributes entry contains field, compareType, and value. field is a non-empty string; value is a string or null.

compareType accepts EQUAL, NOT_EQUAL, CONTAIN, START_WITH, EMPTY, and NOT_EMPTY. EMPTY and NOT_EMPTY need no comparison value; use null. Other comparisons need the value to match. Use "true", not JSON true, and strings for numeric comparison values.

For a standard or linked-attribute request, use an unprefixed field, such as isTemplate or product|name. The application converts pipe-separated paths to dot paths in editable state and serializes them back to pipes for the API.

A linked-object request uses getSelectedObjectForEventId and linkName without metaTypeName. In this strategy, obj:code addresses the linked Object and link:relationKind addresses the Link; an unprefixed field addresses the Object. The application keeps these as obj and link entries in editable state and restores the prefixes in the API body. The following configuration fragment requires the source panel to publish the order-selected selection with addSelectedObjectToRequest. Replace OrderOperation, code, and relationKind with the corresponding names from your backend:

json
{
  "request": {
    "getSelectedObjectForEventId": "order-selected",
    "linkName": "OrderOperation",
    "findAttributes": [
      { "field": "obj:code", "compareType": "START_WITH", "value": "OP-" },
      { "field": "link:relationKind", "compareType": "EQUAL", "value": "primary" }
    ]
  },
  "filter": {
    "fields": [
      { "attribute": "code", "label": "Code" },
      { "attribute": "link.relationKind", "label": "Relation kind" }
    ]
  }
}

The API request contains field: "obj:code" for the Object condition and field: "link:relationKind" for the Link condition. A selected event alone does not turn an attribute-based request into a linked-object request.

Edit, reset, and reopen ​

A Table's filter.fields configures the visible filter dialog. Configure the matching fields there if users need to edit the initial values. Its fields[].attribute names differ from the request's field:

Request strategyConfigured fieldfilter.fields[].attributeAPI field
Standard or linked-attributeproduct|nameproduct.nameproduct|name
Linked-objectobj:code or codecodeobj:code
Linked-objectlink:relationKindlink.relationKindlink:relationKind

Use dot paths in the dialog fields, omit obj:, and replace link: with link.. In the example above, opening the dialog shows OP- in Code and primary in Relation kind. Editing either field and clicking Apply replaces its existing condition. Copying an API-style prefixed name into a dialog field instead addresses a different field; it will not edit the initial condition.

When opened, the dialog copies the current registry filters into its draft. Apply replaces the registry state with the submitted filters, resets the page offset to 0, preserves page size, and triggers the Table query.

Reset clears only the dialog draft; it does not change applied filters or send a request. To clear the applied filters, click Reset, then Apply. Apply writes [] to the registry and triggers a new request. Cancel or closing the dialog before Apply discards the draft and preserves the applied filters.

Sorting, paging, refetching, and remounting reuse the applied state, including [] after Reset followed by Apply; they do not reapply the configured defaults. Initialization runs only when the registry has no findAttributes state for that panel. These are editable defaults, not permanent constraints.

If Table's ordinary object search, linked-attribute search, or linked-object request fails, Table removes the previous rows and clears its previous row selection. It shows Could not load the table and a Retry button; the header and filter controls remain available. Click Retry to request rows with the current applied filters, pagination, and selected parent. While the retry runs, the loading state replaces the error; a successful response replaces it with rows or the empty-result message. This recovery behavior does not describe method, single-object, or custom HTTP requests.

For a linked-attribute request, the request strategy separately adds the selected parent's GUID equality filter. It stays in the outgoing request after Reset followed by Apply; it is not an editable default. The dedicated custom HTTP source does not use these object filters, and the method executor does not forward them. The declared request.filter[] field is not the active filter path.

Sorting ​

Each sortParams entry selects attribute, obj, or link and a direction. Persisted ascending is "ASC"; descending is the legacy value "Desc". The transport normalizes them to API "Asc" and "Desc".

json
{
  "sortParams": [
    { "attribute": "priority", "sortDirection": "Desc" },
    { "attribute": "code", "sortDirection": "ASC" }
  ]
}

Standard and linked strategies send sorting to the server. Custom rows are sorted and paginated in the client. A sortable column only exposes the user interaction; it does not add the attribute to an explicitly configured request.attributeList.

Pagination behavior ​

  • The first pagination.rowsPerPage entry is the initial Table limit.
  • Changing page or page size updates { limit, offset }.
  • Applying a new visible filter resets offset to 0 and preserves the limit.
  • Standard, linked, and linked-attribute requests send pagination to the API.
  • Custom requests slice the complete returned array locally.
  • Without pagination configuration or restored page state, the first object request omits pagination. The renderer's [3, 5, 10, 15] page-size menu and fallback value 3 do not impose a server limit. Configure rowsPerPage explicitly when the initial request must have a known limit.

Minimal valid configuration ​

json
{
  "id": "orders",
  "type": "table",
  "request": { "metaTypeName": "ProductionOrder" },
  "columns": [{ "attribute": "name", "label": "Order" }]
}

Complete master-detail example ​

The following child request cannot run alone: the parent event is its required input.

json
{
  "id": "master-detail",
  "type": "group",
  "groupLayout": { "type": "rows" },
  "panels": [
    {
      "id": "orders",
      "type": "table",
      "request": { "metaTypeName": "ProductionOrder" },
      "events": [
        {
          "id": "order-selected",
          "name": "onObjectSelect",
          "actions": [{ "name": "addSelectedObjectToRequest" }]
        }
      ],
      "columns": [{ "attribute": "code", "label": "Order" }]
    },
    {
      "id": "operations",
      "type": "table",
      "condition": {
        "scenario": "objectSelected",
        "eventId": "order-selected"
      },
      "request": {
        "metaTypeName": "Operation",
        "getSelectedObjectForEventId": "order-selected",
        "linkedAttribute": "order"
      },
      "filter": {
        "fields": [{ "attribute": "status", "label": "Status" }]
      },
      "pagination": { "rowsPerPage": [10, 25] },
      "columns": [
        { "attribute": "code", "label": "Operation", "sortable": true },
        { "attribute": "status", "label": "Status" }
      ]
    }
  ]
}
Open a linked-attribute request with selection and visible filtering Open standard, linked, and single-object request paths

Limits and current drift ​

  • Request fields are not runtime schema-validated before strategy selection.
  • A selected-event request waits on live event state; the event declaration alone does not supply an object.
  • Method requests are implemented by the shared router but incompletely represented in older Table-local types and source documentation.
  • The checked-in method fixture proves the Table transport and response path against the local fixture API. Its method name and dataset remain fixture-specific; production method availability still belongs to the backend contract.
  • request.filter[] is declared in older Table configuration but is not the active filtering model.

Exact property reference ​

Projection and standard requests:

Linked requests:

Method requests:

Custom HTTP requests:

Filters:

Sorting:

Table pagination:

Next tasks ​