> For the complete documentation index, see [llms.txt](https://docs.eximee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/model-danych/struktura-modelu-danych.md).

# Data model structure

## Tree structure

{% columns %}
{% column %}
The data model has a tree structure that facilitates mapping the hierarchical structure of business domain objects.

**Leaves** of the tree represent the most detailed element of the structure. Leaves, called fields, no longer have any other child elements and represent a single data field. Examples may be "customer name" or "bank account number".

**Nodes** of the tree represent objects composed of other objects and/or fields. Examples: "mailing address", "customer income".
{% endcolumn %}

{% column %}

<figure><img src="/files/a15b26932f6fe1b228152aa6a4e2734bb87767d2" alt="" width="216"><figcaption><p><em><strong>Figure 1.</strong> Tree structure</em></p></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

### Nodes

Each node in the data model has the attributes:

* a key unique among its siblings (descendants of the same node)
* cardinality expressed by the formula `n..m` meaning from `n` occurrences at minimum to `m` at maximum, e.g.:
  * `1..1` - the object occurs only once
  * `0..1` - the object is optional
  * `1..null` - the object occurs at least once, with no limit on the maximum number of occurrences
* description of the object's meaning for the application

{% hint style="info" %}
Nodes can therefore be unambiguously identified using a key formed by joining the keys of parent nodes, e.g.: `client.email`.
{% endhint %}

### Leaves

In addition to node attributes, leaves also have:

* data sources - define how and from where the value is retrieved
* default value - what the field will return if none of the data sources returns a value

The field can have a defined list of data sources. Resolving the field value consists of calling the data sources in the order they are defined until a non-empty value is obtained. Therefore, the first source to return a non-empty value wins.

We can retrieve data from the model only for individual keys selected by us, i.e. we cannot retrieve values of keys that have children beneath them, just as we cannot retrieve the entire model in a single query.

## Arrays in the data model <a href="#strukturamodeludanychbudowanieiuzywanie-definiowanietablicowychpolmodeludanych" id="strukturamodeludanychbudowanieiuzywanie-definiowanietablicowychpolmodeludanych"></a>

Nodes of the model marked as multiple (maximum cardinality `>1`) create an array of simple values (for fields) and complex objects (for non-leaf nodes). It is also possible to define nested collections.

### Keys and identifiers <a href="#strukturamodeludanychbudowanieiuzywanie-kluczeiidentyfikatory" id="strukturamodeludanychbudowanieiuzywanie-kluczeiidentyfikatory"></a>

When referring to data model nodes defined as an array (or being descendants of an array), you should always use array notation:

* array\[].field - retrieves all occurrences of the field; depending on the API used, it will return a collection or a single string with the "," separator
* array\[0].field - will retrieve a single value resolved from the collection row indicated in the key (in the example 0 means the first element of the array),
* array.field - will cause an error, it is not possible to refer to an array node without array notation,

### Defining an array <a href="#strukturamodeludanychbudowanieiuzywanie-definiowanietablicywmodeludanych" id="strukturamodeludanychbudowanieiuzywanie-definiowanietablicywmodeludanych"></a>

To define an array field, it is necessary that:

* the multiple node of the data model must have a cardinality greater than `multiplicityMax=1`, e.g. `1..null`,
* the multiple node of the data model must have defined sources pointing to an array; the indices of this collection will be used to index the repetitions of the model value,
* nodes below a multiple data model node can in mapping use the index of the iterated model node to indicate specific elements of the service output,
  * the parent node always makes its current index available in the execution context (while resolving values for the collection) under the identifier *`nodeNameIdx`,*
  * iterated fields of the parent should point to objects inside the collection over which the parent iterates,
  * however, this is not strictly necessary; it is possible to use this index to iterate over a completely different field or to extract fields that are not arrays at all.

{% hint style="info" %}
For example, having a service result that consists of a constant field and two arrays - known to have the same length (arrayA, arrayB, fieldC) - it is possible to create a mapping in which the model iterates over arrayA, but its subfields extract successive fields of arrayB and the constant value from fieldC.
{% endhint %}

## Binding a provider to the data model

A provider is a local data source written in [ScriptCode](https://docs.eximee.com/budowanie-aplikacji/logika-biznesowa/scriptcode/wprowadzenie-do-scriptcode), which defines how values for model fields are obtained. It can be used by fields to supply their values. The data source can be a function:

* script-based,
* calling an external REST service,
* referring to another element of the model,
* retrieving a value from the application configuration.

The provider described below is **a data source for a data model leaf**. It is used to retrieve the current currency exchange rate from an external API (NBP):

* `exchangeRate` is **a leaf (field)** in the tree,
* the field has no children and represents a single value (currency exchange rate),
* can be nested in a node, e.g.: `exchangeRates.exchangeRateEUR`.

<figure><img src="/files/497085aeb639966b068deda41bef37b736b68ea5" alt="przykład z kodem providera"><figcaption><p><em><strong>Figure 2.</strong> Example of a provider retrieving the current currency exchange rate from an API (NBP)</em></p></figcaption></figure>

Flow of operation:

* the key, i.e. the currency code (`currencyCode`), e.g. "EUR" or "USD", is retrieved from the provider's input parameters,
* this value is passed to the provider from the data model,
* the provider executes a GET request to the configured endpoint `nbpExchangeRate` using `api.rest.v1.get`,
* path parameters (`pathParams`) build the request URL in the form: `/rates/A/{currencyCode}` (the letter "A" denotes the table of average exchange rates published by NBP),
* the API response contains the object `body`, which contains the array `rates`, and the first element is retrieved from the array (`rates[0]`), then its field `mid`, which represents the average exchange rate,
* the provider returns an object containing the field `exchangeRate`, the value of this field corresponds to the retrieved currency exchange rate and can be further used in the data model or form.

### Configuration of data sources for a field

Each field in the data model can have **data sources**.\
The configuration is available after clicking the pencil icon next to the selected field, which opens the drawer of data source settings associated with that field. If data sources have already been defined for a given key, their names are visible in the panel - in the example shown, this is `exchangeRateFromNBPProvider`. After selecting a source, it is possible to configure input parameters and output mapping.

<figure><img src="/files/0fbe9c745720dccc6047f216433c50bd53631739" alt="przykład z kodem providera"><figcaption><p><em><strong>Figure 3.</strong> Example of using a provider as a data source in the model</em></p></figcaption></figure>

In the **Parameters** values passed to the provider are defined.\
In the case described:

* key: `currencyCode`
* value: `EUR`

This parameter is used by the provider to call the external API.

In the section **Mapping** it is specified which data from the provider's response will be assigned to the field in the model. In this example, the value `exchangeRate`.

The obtained value can then be used in the data model or directly in the form. More about using the data model on the application can be found in the tab [Data model on the interface](https://docs.eximee.com/~/revisions/6RARJsssdz6tDsOideLu/budowanie-aplikacji/interfejs-uzytkownika/formularze/praca-z-komponentami-bazowymi/model-danych-na-interfejsie).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/model-danych/struktura-modelu-danych.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
