# Configuration

If the App requires configuration and defines configuration form in [configuration\_schema](https://docs.ergonode.com/apps2/manifest#configuration_schema) it has to appropriately handle the values.

It has to be able to validate and persist the configuration and also provide the configuration for reading.

To do so 2 endpoints implementation is necessary.

{% hint style="info" %}
Each endpoint receives an appropriate `X-APP-TOKEN` HTTP header with JWT that allows [authentication](https://docs.ergonode.com/apps2/authentication#authentication-of-the-incoming-request) of the caller.
{% endhint %}

#### \[GET] /configuration

The endpoint should return all so-far persisted schemas in update configuration steps in the form of an array of data - according to your schema.

For example for a simple configuration schema

```json
{
  "configuration_schema": [
    {
      "title": "Connection",
      "type": "object",
      "properties": {
        "token": {
          "type": "string",
          "title": "API token",
          "widget": "password",
          "propertyOrder": 1
        }
      },
      "required": [
        "token"
      ]
    },
    {
      "title": "Settings",
      "type": "object",
      "properties": {
        "setting1": {
          "type": "string",
          "title": "setting 1",
          "propertyOrder": 1
        },
        "setting2": {
          "type": "string",
          "title": "setting 2",
          "propertyOrder": 1
        }
      },
      "required": [
        "text"
      ]
    }
  ]
}
```

the expected response would be

```json
[
  {
    "token": "secret API token"
  },
  {
    "setting1": "user input text 1",
    "setting2": "user input text 2"
  }
]
```

{% hint style="info" %}
Every object represents single form step/one configuration schema.
{% endhint %}

{% hint style="info" %}
Preserving the configured objects under the same indexes as their definitions in the configuration schema is mandatory.
{% endhint %}

#### \[POST] /configuration

The endpoint accepts, validates, and persists in the configuration step.

payload

{% tabs %}
{% tab title="Example" %}

```json
{
  "index": 0,
  "configuration": {
    "text": "user input text"
  }
}
```

{% endtab %}

{% tab title="Schema" %}

```json
{
  "type": "object",
  "properties": {
    "index": {
      "type": "integer",
      "description": "The index of the configuration step from configuration schema."
    },
    "configuration": {
      "type": "object",
      "description": "The form data according to configuration schema."
    }
  },
  "required": [
    "index",
    "configuration"
  ]
}
```

{% endtab %}
{% endtabs %}

All 2xx responses will be treated as success.

#### Error handling

The forms are validated against configuration schema but not all validation can be performed based on JSON schema.

I.e. API token can only be verified in the App.

{% hint style="info" %}
Though the frontend application performs configuration validation on every step it is a good practice to perform full validation in the App as well to limit any potential errors.
{% endhint %}

To assign a custom error message to specific user form fields it is required to return an error response with code 422 and the payload

{% tabs %}
{% tab title="Example" %}

```json
{
  "title": "Form validation errors.",
  "detail": "Token for API is not valid",
  "violations": [
    {
      "propertyPath": "token",
      "title": "Token for API is not valid",
      "template": "Token for %parameter% is not valid",
      "parameters": {
        "%parameter%": "API"
      }
    }
  ]
}
```

{% endtab %}

{% tab title="Schema" %}

```json
{
  "type": "object",
  "properties": {
    "title": {
      "type": "string",
      "description": "The title of an error."
    },
    "detail": {
      "type": "string",
      "description": "Detailed errors description."
    },
    "violations": {
      "type": "array",
      "description": "The list of violations.",
      "items": {
        "type": "object",
        "properties": {
          "propertyPath": {
            "type": "string",
            "description": "Path to the field the violation applies"
          },
          "title": {
            "type": "string",
            "description": "Ready to use message"
          },
          "template": {
            "type": "string",
            "description": "Template of the message"
          },
          "parameters": {
            "type": "object",
            "description": "Parameters of the template"
          }
        }
      }
    }
  },
  "required": [
    "index",
    "configuration"
  ]
}
```

{% endtab %}
{% endtabs %}

All other error codes will be treated with a generic error message.
